1. 程式人生 > 實用技巧 >django-restframework-jwt認證基礎使用等相關內容-89

django-restframework-jwt認證基礎使用等相關內容-89

1 jwt認證介紹

1 不再使用Session認證機制,而使用Json Web Token(本質就是token)認證機制,使用者登入認證
2 使用者只要登入了,返回使用者一個token串(隨機字串),每次使用者發請求,需要攜帶這個串過來,驗證通過,我們認為使用者登入了
3 JWT的構成(字串)
-三部分(每一部分中間通過.分割):header payload signature
-header:明型別,這裡是jwt,宣告加密演算法,頭裡加入公司資訊...,base64轉碼
{
'typ': 'JWT',
'alg': 'HS256'
}
-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,就可以繼續往後訪問

2 base64介紹和使用

1 任何語言都有base64的加碼和解碼,轉碼方式(加密方式)
2 python中base64的加密與解密

import base64

import json
dic_info={
"name": "lqz",
"age": 18
}
# 轉成json格式字串

dic_str=json.dumps(dic_info)
print(dic_str)
#eyJuYW1lIjogImxxeiIsICJhZ2UiOiAxOH0=
#eyJuYW1lIjogImxxeiIsICJhZ2UiOiAxOH0=
# 需要用bytes格式
# 加密
base64_str=base64.b64encode(dic_str.encode('utf-8'))
print(base64_str)


# 解密

res_bytes=base64.b64decode('eyJuYW1lIjogImxxeiIsICJhZ2UiOiAxOH0=')
print(res_bytes)

3 jwt基本使用(jwt內建,控制使用者登入後能訪問和未登陸能訪問)

1 drf中使用jwt,藉助第三方https://github.com/jpadilla/django-rest-framework-jwt
2 pip3 install djangorestframework-jwt
3 快速使用(預設使用auth的user表)
1 再預設auth的user表中建立一個使用者
2 在路由中配置
path('login/', obtain_jwt_token),
3 用postman向這個地址傳送post請求,攜帶使用者名稱,密碼,登陸成功就會返回token

4 obtain_jwt_token本質也是一個檢視類,繼承了APIView
-通過前端傳入的使用者名稱密碼,校驗使用者,如果校驗通過,生成token,返回
-如果校驗失敗,返回錯誤資訊

4 使用者登入以後才能訪問某個介面
-jwt模組內建了認證類,拿過來區域性配置就可以
-class OrderView(APIView):
# 只配它不行,不管是否登入,都能範圍,需要搭配一個內建許可權類
authentication_classes = [JSONWebTokenAuthentication, ]
permission_classes = [IsAuthenticated,]
def get(self, request):
print(request.user.username)
return Response('訂單的資料')

5 使用者未登入,不能訪問
-class OrderView(APIView):
# 只配它不行,不管是否登入,都能範圍,需要搭配一個內建許可權類
authentication_classes = [JSONWebTokenAuthentication, ]
def get(self, request):
print(request.user.username)
return Response('訂單的資料')

6 如果使用者攜帶了token,並且配置了JSONWebTokenAuthentication,從request.user就能拿到當前登入使用者,如果沒有攜帶,當前登入使用者就是匿名使用者

7 前端要傳送請求,攜帶jwt,格式必須如下
-把token放到請求頭中,key為:Authorization
-value必須為:jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo1LCJ1c2VybmFtZSI6ImVnb24xIiwiZXhwIjoxNjA1MjQxMDQzLCJlbWFpbCI6IiJ9.7Y3PQM0imuSBc8CUe_h-Oj-2stdyzXb_U-TEw-F82WE

4 控制登入介面返回的資料格式

1 控制登入介面返回的資料格式如下
{
code:100
msg:登入成功
token:asdfasfd
username:egon
}

2 寫一個函式
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': 'homework.utils.jwt_response_payload_handler',
}

5 自定義基於jwt的認證類

1 自己實現基於jwt的認證類,通過認證,才能繼續訪問,通不過認證就返回錯誤
2 程式碼如下

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, ]