Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DjangoCon - JSON Web Tokens

DjangoCon - JSON Web Tokens

DjangoCon US 2014 talk on JSON Web Tokens

José Padilla

September 04, 2014
Tweet

More Decks by José Padilla

Other Decks in Programming

Transcript

  1. JWT

  2. “Compact URL-safe means of representing claims to be transferred between

    two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS).” - IETF.
  3. JWA

  4. JWK

  5. JWT

  6. JWS

  7. JWE

  8. import json import hmac from hashlib import sha256 from base64

    import urlsafe_b64encode ! segments = [] ! header_dict = { 'typ':'JWT', 'alg': 'HS256' } ! json_header = json.dumps(header_dict) ! header = urlsafe_b64encode(json_header).rstrip('=') segments.append(header) eyJ0eXAiOiJKV1QiLCJhbGciOi JIUzI1NiJ9.eyJ1c2VyX2lkIjo xfQ.xpCS8TTq1a53OIps1ByTdm 6Sh-A1ZoCId3e2YYWjapU
  9. payload_dict = { 'user_id': 1 } ! json_payload = json.dumps(payload)

    ! payload = urlsafe_b64encode(json_payload).rstrip('=') segments.append(payload) eyJ0eXAiOiJKV1QiLCJhbGciOi JIUzI1NiJ9.eyJ1c2VyX2lkIjo xfQ.xpCS8TTq1a53OIps1ByTdm 6Sh-A1ZoCId3e2YYWjapU
  10. SECRET = 'abc123' ! signing_input = '.'.join(segments) ! sig =

    hmac.new(SECRET, signing_input, sha256) signature = urlsafe_b64encode(sig.digest()).rstrip('=') segments.append(signature) ! token = '.'.join(segments) eyJ0eXAiOiJKV1QiLCJhbGciOi JIUzI1NiJ9.eyJ1c2VyX2lkIjo xfQ.xpCS8TTq1a53OIps1ByTdm 6Sh-A1ZoCId3e2YYWjapU
  11. import jwt ! SECRET_KEY = "abc123" payload = {"user_id": 1}

    ! jwt_token = jwt.encode(payload, SECRET_KEY) ! payload = jwt.decode(jwt_token, SECRET_KEY)
  12. import json ! from django.views.generic import View from django.http import

    HttpResponse ! from jwt_auth.mixins import JSONWebTokenAuthMixin ! ! class RestrictedView(JSONWebTokenAuthMixin, View): def get(self, request): data = json.dumps({ 'foo': 'bar' }) return HttpResponse(data, content_type='application/json')
  13. from django.conf.urls import patterns from .views import RestrictedView urlpatterns =

    patterns( '', ! (r'^login/$', 'jwt_auth.views.obtain_jwt_token'), (r'^restricted/$', RestrictedView.as_view()), )
  14. from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.permissions

    import IsAuthenticated from rest_framework_jwt.authentication import JSONWebTokenAuthentication class RestrictedView(APIView): permission_classes = (IsAuthenticated, ) authentication_classes = (JSONWebTokenAuthentication, ) def get(self, request): data = { 'foo': 'bar' } ! return Response(data)
  15. from django.conf.urls import patterns from .views import RestrictedView urlpatterns =

    patterns( '', ! (r'^login/', 'rest_framework_jwt.views.obtain_jwt_token'), (r'^restricted/$', RestrictedView.as_view()), )
  16. var url = 'http://localhost:8000/login/', creds = { username: 'admin', password:

    'abc123' }; $.post(url, creds, function(auth) { $.ajax({ type: 'GET', url: 'http://localhost:8000/restricted/', beforeSend: function(xhr) { xhr.setRequestHeader("Authorization", "Bearer " + auth.token); }, success: function(data){ console.log(data); // { // foo: "bar" // } } }); });
  17. Recap • It’s a standard • It’s simple • Third

    party libraries • Single Sign-on • Action links • Authentication • CORS • Stateless • No CSRF • CDN • Mobile/WebSockets