1 再也不使用Session認證機制,而使用Json Web Token(本質就是token)認證機制,用戶登陸認證 2 用戶只要登陸了,返回用戶一個token串(隨機字符串),每次用戶發請求,須要攜帶這個串過來,驗證經過,咱們認爲用戶登陸了 3 JWT的構成(字符串) -三部分(每一部分中間經過.分割):header payload signature -header:聲明類型,這裏是jwt,聲明加密算法,頭裏加入公司信息...,用base64轉碼 { 'typ': 'JWT', 'alg': 'HS256' #用md5也行 } -payload:荷載(有用),當前用戶的信息(用戶名,id,這個token的過時時間,手機號),用base64轉碼 { "sub": "1234567898", "name": "egon", "admin": true, "userid":1, 'mobile':123444444 } -signature:簽名 -把前面兩部分的內容經過加密算法+密鑰加密後獲得的一個字符串 -jwt總的構成樣子: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ 4 JWT認證原理 -用戶攜帶用戶名,密碼登陸個人系統,校驗經過,生成一個token(三部分),返回給用戶---》登陸功能完成 -訪問須要登陸的接口(用戶中心),必須攜帶token過來,後端拿到token後,把header和payload截出來,再經過同樣的加密方式和密碼獲得一個signature,
和該token的signature比較,若是同樣,表示是正常的token,就能夠繼續日後訪問
安裝前端
1 drf中使用jwt,藉助第三方https://github.com/jpadilla/django-rest-framework-jwt
2 安裝 pip3 install djangorestframework-jwt
快速使用git
3 快速使用(默認使用auth的user表) (1) 在默認auth的user表中建立一個用戶 (2) 在路由中配置 from rest_framework_jwt.views import obtain_jwt_token path('login/', obtain_jwt_token), (3) 用postman向這個地址發送post請求,攜帶用戶名,密碼,登錄成功就會返回token (4)obtain_jwt_token本質也是一個視圖類,繼承了APIView -經過前端傳入的用戶名密碼,校驗用戶,若是校驗經過,生成token,返回 -若是校驗失敗,返回錯誤信息 訪問地址:http://127.0.0.1:8000/homework/login/
用戶登陸之後才能訪問某個接口github
4 用戶登陸之後才能訪問某個接口 -jwt模塊內置了認證類,拿過來局部配置就能夠 -class OrderView(APIView): # 只配它不行,無論是否登陸,都能範圍,須要搭配一個內置權限類 authentication_classes = [JSONWebTokenAuthentication, ] permission_classes = [IsAuthenticated,] def get(self, request): print(request.user.username) return Response('訂單的數據') 訪問地址: http://127.0.0.1:8000/homework/order/ 注意:訪問的時候須要在header內攜帶jwt
用戶未登陸,能夠訪問算法
5 用戶未登陸,能夠訪問 -class OrderView(APIView): # 只配它不行,無論是否登陸,都能範圍,須要搭配一個內置權限類 authentication_classes = [JSONWebTokenAuthentication, ] def get(self, request): print(request.user.username) return Response('訂單的數據') 訪問地址: http://127.0.0.1:8000/homework/order/
注意事項django
6 若是用戶攜帶了token,而且配置了JSONWebTokenAuthentication,從request.user就能拿到當前登陸用戶,若是沒有攜帶,當前登陸用戶就是匿名用戶 7 前端要發送請求,攜帶jwt,格式必須以下 -把token放到請求頭header中,key爲:Authorization -value必須爲:jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo1LCJ1c2VybmFtZSI6ImVnb24xIiwiZXhwIjoxNjA1MjQxMDQzLCJlbWFpbCI6IiJ9.7Y3PQM0imuSBc8CUe_h-Oj-2stdyzXb_U-TEw-F82WE
1 控制登陸接口返回的數據格式以下 { code:100 msg:登陸成功 token:asdfasfd username:egon } 2 寫一個函數utils.py from homework.serializer import UserReadOnlyModelSerializer def jwt_response_payload_handler(token, user=None, request=None): return {'code': 100, 'msg': '登陸成功', 'token': token, 'user': UserReadOnlyModelSerializer(instance=user).data } 3 在setting.py中配置 import datetime JWT_AUTH = { 'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.utils.jwt_response_payload_handler', }
1 本身實現基於jwt的認證類,經過認證,才能繼續訪問,通不過認證就返回錯誤
2 本身寫個類auth.py class JwtAuthentication(BaseJSONWebTokenAuthentication): def authenticate(self, request): # 認證邏輯() # token信息能夠放在請求頭中,請求地址中 # key值能夠隨意叫 # token=request.GET.get('token') token=request.META.get('HTTP_Authorization'.upper()) # 校驗token是否合法 try: payload = jwt_decode_handler(token) except jwt.ExpiredSignature: raise AuthenticationFailed('過時了') except jwt.DecodeError: raise AuthenticationFailed('解碼錯誤') except jwt.InvalidTokenError: raise AuthenticationFailed('不合法的token') user=self.authenticate_credentials(payload) return (user, token)
3 在視圖類中配置 authentication_classes = [JwtAuthentication, ] # 視圖views.py全代碼: from app01.auth import JwtAuthentication class OrderView(APIView): # 登陸之後才能訪問 authentication_classes = [JwtAuthentication, ] def get(self, request): print(request.user.username) return Response('訂單的數據')