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

    View Slide

  2. “jot”

    View Slide

  3. JSON Web Tokens

    View Slide

  4. José Padilla

    View Slide

  5. Flickr: Bryan Vincent

    View Slide

  6. Co-founder at
    blimp.io

    View Slide

  7. /jpadilla

    View Slide

  8. jpadilla.com

    View Slide

  9. Why?

    View Slide

  10. Single Sign-on

    View Slide

  11. Action Links

    View Slide

  12. Webhooks

    View Slide

  13. Token-based Auth

    View Slide

  14. What?

    View Slide

  15. “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.

    View Slide

  16. View Slide

  17. View Slide

  18. View Slide

  19. View Slide

  20. View Slide

  21. View Slide

  22. JOSE

    View Slide

  23. JavaScript
    Object
    Signing and
    Encryption

    View Slide

  24. JWA

    View Slide

  25. JSON
    Web
    Algorithms

    View Slide

  26. JWK

    View Slide

  27. JSON
    Web
    Key

    View Slide

  28. JWT

    View Slide

  29. JSON
    Web
    Token

    View Slide

  30. JWS

    View Slide

  31. JSON
    Web
    Signature

    View Slide

  32. JWE

    View Slide

  33. JSON
    Web
    Encryption

    View Slide

  34. Today it’s
    all about
    JWT

    View Slide

  35. How?

    View Slide

  36. Internet-Draft

    View Slide

  37. eyJ0eXAiOiJKV1QiLCJhbGciOi
    JIUzI1NiJ9.eyJ1c2VyX2lkIjo
    xfQ.xpCS8TTq1a53OIps1ByTdm
    6Sh-A1ZoCId3e2YYWjapU

    View Slide

  38. eyJ0eXAiOiJKV1QiLCJhbGciOi
    JIUzI1NiJ9.eyJ1c2VyX2lkIjo
    xfQ.xpCS8TTq1a53OIps1ByTdm
    6Sh-A1ZoCId3e2YYWjapU

    View Slide

  39. {
    "typ": "JWT",
    "alg": "HS256"
    }
    eyJ0eXAiOiJKV1QiLCJhbGciOi
    JIUzI1NiJ9.eyJ1c2VyX2lkIjo
    xfQ.xpCS8TTq1a53OIps1ByTdm
    6Sh-A1ZoCId3e2YYWjapU

    View Slide

  40. 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

    View Slide

  41. eyJ0eXAiOiJKV1QiLCJhbGciOi
    JIUzI1NiJ9.eyJ1c2VyX2lkIjo
    xfQ.xpCS8TTq1a53OIps1ByTdm
    6Sh-A1ZoCId3e2YYWjapU

    View Slide

  42. {!
    "user_id": 1!
    }
    eyJ0eXAiOiJKV1QiLCJhbGciOi
    JIUzI1NiJ9.eyJ1c2VyX2lkIjo
    xfQ.xpCS8TTq1a53OIps1ByTdm
    6Sh-A1ZoCId3e2YYWjapU

    View Slide

  43. 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

    View Slide

  44. eyJ0eXAiOiJKV1QiLCJhbGciOi
    JIUzI1NiJ9.eyJ1c2VyX2lkIjo
    xfQ.xpCS8TTq1a53OIps1ByTdm
    6Sh-A1ZoCId3e2YYWjapU

    View Slide

  45. 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

    View Slide

  46. eyJ0eXAiOiJKV1QiLCJhbGciOi
    JIUzI1NiJ9.eyJ1c2VyX2lkIjo
    xfQ.xpCS8TTq1a53OIps1ByTdm
    6Sh-A1ZoCId3e2YYWjapU

    View Slide

  47. PyJWT

    View Slide

  48. $ pip install PyJWT

    View Slide

  49. import jwt
    !
    SECRET_KEY = "abc123"
    payload = {"user_id": 1}
    !
    jwt_token = jwt.encode(payload, SECRET_KEY)
    !
    payload = jwt.decode(jwt_token, SECRET_KEY)

    View Slide

  50. /progrium/pyjwt

    View Slide

  51. Django JWT Auth

    View Slide

  52. username/password
    JWT
    Error
    /login

    View Slide

  53. Authorization: Bearer
    JWT
    Error
    /restricted

    View Slide

  54. $ pip install django-jwt

    View Slide

  55. 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')

    View Slide

  56. 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()),
    )

    View Slide

  57. /jpadilla/django-jwt-auth

    View Slide

  58. DRF JWT Auth

    View Slide

  59. $ pip install djangorestframework-jwt

    View Slide

  60. 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)

    View Slide

  61. 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()),
    )

    View Slide

  62. 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"
    // }
    }
    });
    });

    View Slide

  63. /GetBlimp/django-rest-framework-jwt

    View Slide

  64. Recap
    • It’s a standard

    • It’s simple

    • Third party libraries

    • Single Sign-on

    • Action links
    • Authentication

    • CORS

    • Stateless

    • No CSRF

    • CDN

    • Mobile/WebSockets

    View Slide

  65. Django
    REST

    Framework
    Sprint

    View Slide

  66. Thanks
    Questions?
    http:/
    /bit.ly/djangocon-jwt

    View Slide