Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
DjangoCon - JSON Web Tokens
Search
José Padilla
September 04, 2014
Programming
15
11k
DjangoCon - JSON Web Tokens
DjangoCon US 2014 talk on JSON Web Tokens
José Padilla
September 04, 2014
Tweet
Share
More Decks by José Padilla
See All by José Padilla
Python, Government, and Contracts
jpadilla
0
51
Python, Government, and Contracts
jpadilla
0
5k
Python Type Hints
jpadilla
0
520
Developer Ergonomics
jpadilla
0
2.1k
BFTW: The Backend
jpadilla
4
200
eventos
jpadilla
0
170
JWT
jpadilla
2
440
Ember.js + Django
jpadilla
3
2.1k
UPRB Basic Workshop
jpadilla
2
210
Other Decks in Programming
See All in Programming
Claude Codeで実装以外の開発フロー、どこまで自動化できるか?失敗と成功
ndadayo
3
1.8k
あのころの iPod を どうにか再生させたい
orumin
2
2.6k
Jakarta EE Core Profile and Helidon - Speed, Simplicity, and AI Integration
ivargrimstad
0
260
パスタの技術
yusukebe
1
540
20250808_AIAgent勉強会_ClaudeCodeデータ分析の実運用〜競馬を題材に回収率100%の先を目指すメソッドとは〜
kkakeru
0
210
Oracle Database Technology Night 92 Database Connection control FAN-AC
oracle4engineer
PRO
1
340
Kiroで始めるAI-DLC
kaonash
2
440
TanStack DB ~状態管理の新しい考え方~
bmthd
2
370
あなたとJIT, 今すぐアセンブ ル
sisshiki1969
1
760
MCPとデザインシステムに立脚したデザインと実装の融合
yukukotani
0
180
🔨 小さなビルドシステムを作る
momeemt
2
620
フロントエンドのmonorepo化と責務分離のリアーキテクト
kajitack
2
150
Featured
See All Featured
The Language of Interfaces
destraynor
160
25k
Being A Developer After 40
akosma
90
590k
Why You Should Never Use an ORM
jnunemaker
PRO
59
9.5k
GraphQLとの向き合い方2022年版
quramy
49
14k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4k
Why Our Code Smells
bkeepers
PRO
339
57k
Statistics for Hackers
jakevdp
799
220k
The Cost Of JavaScript in 2023
addyosmani
53
8.9k
Designing for humans not robots
tammielis
253
25k
The Art of Programming - Codeland 2020
erikaheidi
55
13k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
131
19k
Imperfection Machines: The Place of Print at Facebook
scottboms
268
13k
Transcript
JWT
“jot”
JSON Web Tokens
José Padilla
Flickr: Bryan Vincent
Co-founder at blimp.io
/jpadilla
jpadilla.com
Why?
Single Sign-on
Action Links
Webhooks
Token-based Auth
What?
“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.
None
None
None
None
None
None
JOSE
JavaScript Object Signing and Encryption
JWA
JSON Web Algorithms
JWK
JSON Web Key
JWT
JSON Web Token
JWS
JSON Web Signature
JWE
JSON Web Encryption
Today it’s all about JWT
How?
Internet-Draft
eyJ0eXAiOiJKV1QiLCJhbGciOi JIUzI1NiJ9.eyJ1c2VyX2lkIjo xfQ.xpCS8TTq1a53OIps1ByTdm 6Sh-A1ZoCId3e2YYWjapU
eyJ0eXAiOiJKV1QiLCJhbGciOi JIUzI1NiJ9.eyJ1c2VyX2lkIjo xfQ.xpCS8TTq1a53OIps1ByTdm 6Sh-A1ZoCId3e2YYWjapU
{ "typ": "JWT", "alg": "HS256" } eyJ0eXAiOiJKV1QiLCJhbGciOi JIUzI1NiJ9.eyJ1c2VyX2lkIjo xfQ.xpCS8TTq1a53OIps1ByTdm 6Sh-A1ZoCId3e2YYWjapU
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
eyJ0eXAiOiJKV1QiLCJhbGciOi JIUzI1NiJ9.eyJ1c2VyX2lkIjo xfQ.xpCS8TTq1a53OIps1ByTdm 6Sh-A1ZoCId3e2YYWjapU
{! "user_id": 1! } eyJ0eXAiOiJKV1QiLCJhbGciOi JIUzI1NiJ9.eyJ1c2VyX2lkIjo xfQ.xpCS8TTq1a53OIps1ByTdm 6Sh-A1ZoCId3e2YYWjapU
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
eyJ0eXAiOiJKV1QiLCJhbGciOi JIUzI1NiJ9.eyJ1c2VyX2lkIjo xfQ.xpCS8TTq1a53OIps1ByTdm 6Sh-A1ZoCId3e2YYWjapU
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
eyJ0eXAiOiJKV1QiLCJhbGciOi JIUzI1NiJ9.eyJ1c2VyX2lkIjo xfQ.xpCS8TTq1a53OIps1ByTdm 6Sh-A1ZoCId3e2YYWjapU
PyJWT
$ pip install PyJWT
import jwt ! SECRET_KEY = "abc123" payload = {"user_id": 1}
! jwt_token = jwt.encode(payload, SECRET_KEY) ! payload = jwt.decode(jwt_token, SECRET_KEY)
/progrium/pyjwt
Django JWT Auth
username/password JWT Error /login
Authorization: Bearer <JWT> JWT Error /restricted
$ pip install django-jwt
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')
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()), )
/jpadilla/django-jwt-auth
DRF JWT Auth
$ pip install djangorestframework-jwt
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)
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()), )
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" // } } }); });
/GetBlimp/django-rest-framework-jwt
Recap • It’s a standard • It’s simple • Third
party libraries • Single Sign-on • Action links • Authentication • CORS • Stateless • No CSRF • CDN • Mobile/WebSockets
Django REST Framework Sprint
Thanks Questions? http:/ /bit.ly/djangocon-jwt