DjangoCon - JSON Web Tokens

Becd166a81dc51c0009f602d175d0cc8?s=47 José Padilla
September 04, 2014

DjangoCon - JSON Web Tokens

DjangoCon US 2014 talk on JSON Web Tokens

Becd166a81dc51c0009f602d175d0cc8?s=128

José Padilla

September 04, 2014
Tweet

Transcript

  1. JWT

  2. “jot”

  3. JSON Web Tokens

  4. José Padilla

  5. Flickr: Bryan Vincent

  6. Co-founder at blimp.io

  7. /jpadilla

  8. jpadilla.com

  9. Why?

  10. Single Sign-on

  11. Action Links

  12. Webhooks

  13. Token-based Auth

  14. What?

  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.
  16. None
  17. None
  18. None
  19. None
  20. None
  21. None
  22. JOSE

  23. JavaScript Object Signing and Encryption

  24. JWA

  25. JSON Web Algorithms

  26. JWK

  27. JSON Web Key

  28. JWT

  29. JSON Web Token

  30. JWS

  31. JSON Web Signature

  32. JWE

  33. JSON Web Encryption

  34. Today it’s all about JWT

  35. How?

  36. Internet-Draft

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

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

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

  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
  41. eyJ0eXAiOiJKV1QiLCJhbGciOi JIUzI1NiJ9.eyJ1c2VyX2lkIjo xfQ.xpCS8TTq1a53OIps1ByTdm 6Sh-A1ZoCId3e2YYWjapU

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

  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
  44. eyJ0eXAiOiJKV1QiLCJhbGciOi JIUzI1NiJ9.eyJ1c2VyX2lkIjo xfQ.xpCS8TTq1a53OIps1ByTdm 6Sh-A1ZoCId3e2YYWjapU

  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
  46. eyJ0eXAiOiJKV1QiLCJhbGciOi JIUzI1NiJ9.eyJ1c2VyX2lkIjo xfQ.xpCS8TTq1a53OIps1ByTdm 6Sh-A1ZoCId3e2YYWjapU

  47. PyJWT

  48. $ pip install PyJWT

  49. import jwt ! SECRET_KEY = "abc123" payload = {"user_id": 1}

    ! jwt_token = jwt.encode(payload, SECRET_KEY) ! payload = jwt.decode(jwt_token, SECRET_KEY)
  50. /progrium/pyjwt

  51. Django JWT Auth

  52. username/password JWT Error /login

  53. Authorization: Bearer <JWT> JWT Error /restricted

  54. $ pip install django-jwt

  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')
  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()), )
  57. /jpadilla/django-jwt-auth

  58. DRF JWT Auth

  59. $ pip install djangorestframework-jwt

  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)
  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()), )
  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" // } } }); });
  63. /GetBlimp/django-rest-framework-jwt

  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
  65. Django REST
 Framework Sprint

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