django restframework jwt

既然要來學習jwt(json web token),那麼咱們確定是先要了解jwt的優點以及應用場景--跨域認證。python

 

$ pip install djangorestframework-jwt

  

傳統cookie-session認證步驟:

一、用戶向服務器發送用戶名和密碼。web

二、服務器驗證經過後,在當前對話(session)裏面保存相關數據,好比用戶角色、登陸時間等等。django

在django session表中,session_key,session_data,expire_date.其中session_data保存的是base64編碼後的用戶對象。json

import base64

r = base64.b64decode("NDQ3OGI4MDA3YTI3MzM2NTQ5ZjhhZGZhNzM0ZjM2OWNlOTFmYWQ0ODp7Il9hdXRoX3VzZXJfaWQiOiIxIiwiX2F1dGhfdXNlcl9iYWNrZW5kIjoiZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5kcy5Nb2RlbEJhY2tlbmQiLCJfYXV0aF91c2VyX2hhc2giOiIyOTBkMjY0YzY3MmMyYmNjZWFiZDRkZWJlZGJjMmQyM2QzNzI5YjBkIn0=")
print(r)

>>>
b'4478b8007a27336549f8adfa734f369ce91fad48:{"_auth_user_id":"1","_auth_user_backend":"django.contrib.auth.backends.ModelBackend","_auth_user_hash":"290d264c672c2bcceabd4debedbc2d23d3729b0d"}'

   

三、服務器向用戶返回一個 session_id,寫入用戶的 Cookie。後端

四、用戶隨後的每一次請求,都會經過 Cookie,將 session_id 傳回服務器。api

五、服務器收到 session_id,找到前期保存的數據,由此得知用戶的身份。跨域

 

這種模式的問題在於,擴展性很差。單機固然沒有問題,若是是服務器集羣,或者是跨域的服務導向架構,就要求 session 數據共享,每臺服務器都可以讀取 session。服務器

 

jwt原理

由header,payload,signature三個部分組成cookie

舉個栗子session

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6InJvb3QiLCJleHAiOjE1NTI5NzE5ODIsImVtYWlsIjoiMTc4NTg4MDQyNjRAMTYzLmNvbSJ9.KuZq40SkiEz9La1wzXy20irjbckNJ0SNWq2EvXBwf0A

 每部分由.分隔,其中header和payload可由base64直接decode可得

header

{"typ":"JWT","alg":"HS256"}

payload

用戶信息,django中取決於UserProfile,UserProfileSerializer

signature

對前兩部分的簽名,防止數據被篡改。指定一個密鑰,使用header中的加密方式

token = base64.b64encode(bytes_header)+"."+base64.b64encode(bytes_payload)+"."+secret

 

django restframework jwt 集成

settings.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),
}

JWT_AUTH = {
    # 指明token的有效期
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
}

  

  • BasicAuthentication

該認證方案使用 HTTP Basic Authentication,並根據用戶的用戶名和密碼進行簽名。Basic Authentication 一般只適用於測試。

  • SessionAuthentication

此認證方案使用 Django 的默認 session 後端進行認證。Session 身份驗證適用於與您的網站在同一會話環境中運行的 AJAX 客戶端。

urls.py

from rest_framework_jwt.views import obtain_jwt_token


urlpatterns = [
    # ...
    url(r'^api-token-auth/', obtain_jwt_token),
]

  

集成完後的測試代碼

import json

import requests


# 驗證jwt
url = "http://127.0.0.1:8000/api-token-auth/?format=json"
data = {
    "username": "root",
    "password": "Admin123."
}
# data = json.dumps(data)
res = requests.post(url,data=data)
token = res.text
print("token:",token)

token = json.loads(token).get("token")
user_url = "http://127.0.0.1:8000/users/?format=json"
headers = {
    "Authorization":"JWT "+ token
}
res = requests.get(user_url,headers=headers)
print(res.text)

  

本身實現jwt也很是簡單

1) base64加HS256 手寫token

2) middleware 驗證token

上述1和2的傳遞是經過request參數,驗證成功後只須要咱們賦予request.user 一個user對象便可。

相關文章
相關標籤/搜索