JWT文档参考
安装
pip install djangorestframework-simplejwt
默认官方提供的三个接口
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
TokenVerifyView
)
urlpatterns = [
...
# 通过获取用户传过来的username.pwd, 验证通过返回refresh, access
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
# 通过获取传过来的refresh, 返回access
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
# 通过获取传来的access, 通过则返回空字典
path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
...
]
重写通过的三个验证接口
- 重写生成令牌的token加密内容, 与生成令牌时的返回值
- 重写校验令牌,解密内容返回 序列化&视图
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer, TokenVerifySerializer
from rest_framework_simplejwt.views import TokenObtainPairView, TokenViewBase
from jwt import decode as jwt_decode
from django.conf import settings
import pendulum
import time
# 生成令牌序列号器
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
# 令牌内的加密内容token
@classmethod
def get_token(cls, user):
token = super().get_token(user)
# Add custom claims
token['username'] = user.username
token['email'] = user.email
# print(f'生产令牌的token:"{token}')
return token
# 生产令牌返回的数据
def validate(self, attrs):
data = super().validate(attrs)
refresh = self.get_token(self.user)
data['refresh'] = str(refresh)
data['access'] = str(refresh.access_token)
data['username'] = str(refresh.get('username'))
data['user_id'] = str(refresh.get('user_id'))
data['email'] = str(refresh.get('email'))
# print(f'生成令牌的校验data:{data}')
return data
# 生产令牌视图
class MyTokenObtainPairView(TokenObtainPairView):
serializer_class = MyTokenObtainPairSerializer
def pu_time(b_time):
try:
p_t = pendulum.parse(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(b_time)),tz="Asia/Shanghai")
pendulum.set_locale('zh')
return p_t.diff_for_humans()
except Exception as e:
print(f"时间人性化失败:{e}")
return f"时间人性化失败:{e}"
# 验证token令牌序列化器
class MyTokenVerifySerializer(TokenVerifySerializer):
def validate(self, attrs):
super().validate(attrs)
decode_data = jwt_decode(attrs['token'], settings.SECRET_KEY, algorithms=["HS256"])
decode_data['exp_time'] = pu_time(decode_data.get('exp')) # 过期时间
decode_data['ipx_time'] = pu_time(decode_data.get('ixp')) # 生成时间
decode_data['df_t'] =decode_data.get('exp') - time.time() # 过期时间差
return decode_data
# 验证序列号器视图
class MyTokenVerifyView(TokenViewBase):
serializer_class = MyTokenVerifySerializer
# {
# "token_type": "access",
# "exp": 1670753730, # 令牌过期时间
# "iat": 1670735727, # 令牌生成时间
# "jti": "67b5cc005b2247408acd99db04411fd3",
# "user_id": 1,
# "username": "陈海峰",
# "email": "1743309009@qq.com"
# }