從請求頭中(Authorization)獲取認證信息(token)算法
若是沒有拿到認證信息,直接斷定該請求爲匿名請求(遊客) => 表明認證經過了,返回None數據庫
django
若是拿到的認證信息,進行信息校驗,校驗失敗了,就拋出異常json
通常認證組件在settings中進行全局配置api
咱們通常都不須要自定義認證類,在settings中全局配置第三方 jwt 認證組件提供的認證類便可,若是要自定義認證類步驟以下:安全
自定義認證類,首先繼承 BaseAuthentication 類服務器
必須重寫 authenticate(self, request) 方法cookie
沒有認證信息,返回None:匿名用戶(遊客) => 匿名用戶request.user也有值,就是"匿名對象(Anonymous)"session
有認證信息,且經過,返回(user, token):合法用戶 => user對象會存到request.user中框架
有認證信息,不經過,拋異常:非法用戶
權限組件只有在認證經過後,再會執行,權限組件的目的就是判斷認證經過的用戶(匿名用戶、有權限用戶)
權限規則其實就是條件邏輯,有權限就返回True => 表明權限經過
條件邏輯判斷失敗,表明用戶沒有權限,返回False => 權限失敗
權限組件通知在視圖類中局部配置
咱們通常在視圖類中局部配置drf提供的權限類,可是也會自定義權限類完成局部配置
自定義權限類,首先繼承 BasePermission 類
必須重寫 has_permission(self, request, view): 方法
設置權限條件,條件經過,返回True => 有權限
設置權限條件,條件不經過,返回False => 沒有權限
drf提供的權限類:
AllowAny:匿名與合法用戶均可以
IsAuthenticated:必須登陸,只有合法用戶能夠
IsAdminUser:必須是admin後臺用戶
IsAuthenticatedOrReadOnly:匿名只讀,合法用戶無限制
from rest_framework.permissions import AllowAny, IsAuthenticated, IsAdminUser, IsAuthenticatedOrReadOnly class UserCenterViewSet(GenericViewSet, mixins.RetrieveModelMixin): permission_classes = [IsAuthenticated, ] queryset = models.User.objects.filter(is_active=True).all() serializer_class = serializers.UserCenterSerializer
沒有數據庫寫操做 => 高效
服務器不存在token => 低耗
簽發校驗都是算法 => 集羣
一、jwt分三段式:頭.體.簽名 (head.payload.sign)
二、頭和體是可逆加密,讓服務器能夠反解出user對象;簽名是不可逆加密,保證整個token的安全性
三、頭.體.簽名三部分,都是採用json格式的字符串進行加密,可逆加密通常採用base64算法,不可逆加密通常採用hash(md5)算法
四、頭中的內容是基本信息:公司信息、項目組信息、token採用的加密方式信息(通常不會變)
五、體中的內容是關鍵性信息:用戶主鍵、用戶名、簽發是客戶端信息(設備號、地址)、過時時間
六、簽名中的內容是安全信息:頭的加密結果+體的加密結果+服務器不對外公開的安全碼,進行 md5 加密,{"head":"頭的加密字符串","payload":"體的加密字符串","secret_key": "安全碼"}
用基本信息存儲json字典,採用base64算法加密獲得 頭字符串
用關鍵信息存儲json字典,採用base64算法加密獲得 體字符串
用頭加密字符串+體加密字符串+安全碼信息存儲json字典,採用hash md5算法加密獲得 簽名字符串
帳戶密碼就能根據User表獲得user對象,造成的三段字符串用 . 拼接成token返回給前臺
將token按 . 拆分爲三段字符串,第一段:頭加密字符串,通常不須要作任何處理
第二段:體加密字符串,要反解出用戶主鍵,經過主鍵從User表中就能獲得登陸用戶,過時時間和設備信息都是安全信息,確保token沒過時,且同一個設備來的
再用 第一段+第二段+服務器安全碼 不可逆md5加密,與第三段簽名字符串進行對比校驗,經過後才能表明第二段校驗的user對象是合法用戶
用帳號密碼訪問登陸接口,登陸接口邏輯中調用 簽發token算法,獲得token,返回給客戶端,客戶端本身存到cookies中
校驗token的算法應該寫在認證類中(在認證類中調用),全局配置給認證組件,全部視圖類請求,都會進行認證校驗,因此請求帶了token,就會反解出user對象,在視圖類中用request.user就能訪問登陸的用戶
注:登陸接口須要作認證+權限兩個局部禁用
pip install djangorestframework-jwt
# api/urls.py urlpatterns = [ ... url('^login/$', ObtainJSONWebToken.as_view()), ] # Postman請求:/api/login/,提供username和password便可
# drf-jwt的配置 import datetime JWT_AUTH = { # 配置過時時間 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7), } # drf配置(把配置放在最下方) REST_FRAMEWORK = { # 自定義三大認證配置類們 'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework_jwt.authentication.JSONWebTokenAuthentication'], # 'DEFAULT_PERMISSION_CLASSES': [], # 'DEFAULT_THROTTLE_CLASSES': [], }
from rest_framework.permissions import IsAuthenticated class UserCenterViewSet(GenericViewSet, mixins.RetrieveModelMixin): # 設置必須登陸才能訪問的權限類 permission_classes = [IsAuthenticated, ] queryset = models.User.objects.filter(is_active=True).all() serializer_class = serializers.UserCenterSerializer
測試:
1)用 {"username": "你的用戶", "password": "你的密碼"} 訪問 post請求 /api/login/ 接口拿到 token 字符串
2)在請求頭用 Authorization 攜帶 "jwt 登陸獲得的token" 訪問 get請求 /api/user/center/1/ 接口訪問我的中心