全稱:json web token 解釋:加密字符串的原始數據是json,後臺產生,經過web傳輸給前臺存儲 格式:三段式 - 頭.載荷.簽名 - 頭和載荷用的是base64可逆加密,簽名用md5不可逆加密 內容: 頭(基礎信息,也能夠爲空):加密方式、公司信息、項目組信息、... 載荷(核心信息):用戶信息、過時時間、... 簽名(安全保障):頭加密結果+載荷加密結果+服務器祕鑰 的md5加密結果html
認證規則: 後臺必定要保障 服務器祕鑰 的安全性(它是jwt的惟一安全保障) 後臺簽發token(login接口 ) -> 前臺存儲 -> 發送須要認證的請求帶着token -> 後臺校驗獲得合法的用戶 -> 權限管理前端
爲何要有jwt認證: 1)服務器壓力小, 後臺不須要存儲token,只須要存儲簽發與校驗token的算法,效率遠遠大於後臺存儲和取出token完成校驗 2) jwt算法認證,更適合服務器集羣部署python
安裝:pip install djangorestframework-jwt 模塊包:rest_framework_jwtweb
採用drf-jwt框架,後期任務只須要書寫登陸 爲何要重寫登陸:drf-jwt只完成了帳號密碼登陸,咱們還須要手機登陸,郵箱登陸 爲何不須要重寫認證類:由於認證規則已經完成且固定不變,變得只有認證字符串的前綴,前綴能夠在配置文件中配置算法
jwt配置;django
在settings.py文件中配置,若是不配置,默認走jwt默認的json
jwt插件的三個接口:api
在urls.py中配置安全
在postman中測試一下籤發token服務器
注意:上面三個接口都是發送POST請求
注:APIResponse 爲自定義Response對象
# views.py from rest_framework.views import APIView from . import models,serializers from utils.response import APIResponse class LoginAPIView(APIView): # 登陸接口應該禁用全部的認證和、權限,由於無論是誰都應該能進來 authentication_classes = [] permission_classes = [] def post(self, request, *args, **kwargs): # 將數據傳到序列化組件進行校驗 user_ser = serializers.LoginSerializer(data=request.data) user_ser.is_valid(raise_exception=True) return APIResponse(msg='login success', data={ 'username': user_ser.user.username, 'token': user_ser.token })
注意:
經過user對象生成payload載荷 payload = jwt_payload_handler(user)
經過payload簽發token token = jwt_encode_handler(payload)
# serializer.py from rest_framework.serializers import ModelSerializer, CharField, ValidationError, SerializerMethodField from . import models from django.contrib.auth import authenticate import re from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler class LoginSerializer(ModelSerializer): username = CharField(write_only=True) password = CharField(write_only=True) class Meta: model = models.User fields = ('username', 'password') def validate(self, attrs): # user_obj = authenticate(**attrs) # if not user_obj: # raise ValidationError('用戶名或密碼錯誤') # 帳號密碼登陸 ==》 多方式登陸 user = self._many_method_login(**attrs) # 經過user對象生成payload載荷 payload = jwt_payload_handler(user) # 經過payload簽發token token = jwt_encode_handler(payload) # 將user和token存放在序列化對象中,方便返回到前端去 self.user = user self.token = token return attrs # 多方式登陸 (用戶名、郵箱、手機號三種方式登陸) def _many_method_login(self, **attrs): username = attrs.get('username') password = attrs.get('password') # 利用正則匹配判斷用戶輸入的信息 # 1.判斷郵箱登陸 if re.match(r'.*@.*', username): user = models.User.objects.filter(email=username).first() # type: models.User # 2.判斷手機號登陸 elif re.match(r'^1[3-9][0-9]{9}$',username): user = models.User.objects.filter(mobile=username).first() # 3.用戶名登陸 else: user = models.User.objects.filter(username=username).first() if not user: raise ValidationError({'username': '帳號有誤'}) if not user.check_password(password): raise ValidationError({'password': '密碼錯誤'}) return user
使用postman測試代碼:
""" 1)任何人都能直接訪問的接口 請求不是是get、仍是post等,不須要作任何校驗 2)必須登陸後才能訪問的接口 任何請求方式均可能作該方式的限制,請求必須在請求頭中攜帶認證信息 - authorization 3)前臺的認證信息獲取只能經過登陸接口 前臺提供帳號密碼等信息,去後臺換認證信息token 4)前臺如何完成登陸註銷 前臺登陸成功通常在cookie中保存認證信息token,分離註銷就是前臺主動清除保存的token信息 """
原文出處:https://www.cnblogs.com/guapitomjoy/p/11939050.html