開發組在開發過程當中,都不可避免地遇到了一些困難或問題,但都最終想出辦法克服了。咱們認爲這樣的經驗是有必要記錄下來的,所以就有了【技術博客】。html
<br /> # JWT的認證機制Django項目中應用python
這篇技術博客基於軟件工程課程的VisualPytorch之上。本文小部分參考了https://jwt.io/introduction/git
在作絕大部分數據庫系統時(網站、小程序),登陸註冊確定是一個繞不開的功能。通常來講傳統的解決方案是基於session機制的認證,也就是客戶端發送用戶名密碼給服務器,服務器端驗證後建立一個session,把session的id返回客戶端,客戶端每次請求時帶着session的id以此做爲驗證。github
從個人視角來看主要存在兩個問題:數據庫
session通常保存在內存中,固然比較大的應用保存在Redis這類數據庫中,經過session_id來作認證增長了訪存次數,影響性能。django
若是你的應用須要支持經過微信號、QQ號登陸,session_id的方式顯然很成問題,畢竟你不可能拿到騰訊的數據庫裏的內容。小程序
這裏就考慮了使用JWT機制來進行認證。JWT全稱是JSON WEB TOKEN,若是使用JWT進行認證,服務器端不須要保存信息,由於JWT將信息加密到了token裏。用戶只須要每次請求的時候帶着token便可,服務器會本身解密。後端
須要補充的一點是,JWT和session機制並不衝突,若是你的應用對於session有需求,可使用JWT作認證,session作其餘需求。服務器
若是想比較詳細地瞭解JWT,能夠參考RFC7519。微信
有一個基於Django Restful接口的包能夠用
pip install djangorestframework-jwt
詳細使用方法參照官方文檔。
該中間件主要提供了三個接口
#得到token from rest_framework_jwt.views import obtain_jwt_token #刷新token from rest_framework_jwt.views import refresh_jwt_token #驗證token from rest_framework_jwt.views import verify_jwt_token
登陸時調用obtain_jwt_token便可。
而對於須要驗證用戶權限的接口,須要在settings.py中添加
'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication' ]
隨後在接口層中增長鬚要的權限便可自動利用jwt來驗證(不須要調用上文提到的verify_jwt_token),例如
permission_classes = (permissions.IsAuthenticated,)
這個其實和JWT無關,和Django有關,但既然都是一個項目下的,不妨多寫一下,以防有需求。
方法重寫Django中User的的後端類中的authenticate方法,而且在settings.py中添加
AUTHENTICATION_BACKENDS = [ 'user.utils.UserAuthBackend', # 修改auth認證後端類,這裏要寫你本身新寫的驗證類 ]
我重寫驗證方法的代碼以下,僅供參考
from django.contrib.auth.backends import ModelBackend from .models import User from django.db.models import Q class UserAuthBackend(ModelBackend): def authenticate(self, request, username=None, password=None, **kwargs): # 郵箱或用戶名登陸 try: user = User.objects.get(Q(username=username) | Q(email=username)) except User.DoesNotExist: return None else: if user.check_password(password) and self.user_can_authenticate(user): return user
這個中間價的默認設置一個token有效時間爲300s,token與其子孫token的過時時間爲7天。
也就是說每隔300s都必須刷新當前的token,而隔7天的話刷新也無用必須從新獲取。
須要更改設置能夠參考官方文檔。 <br /><br />