安装rest_framework_simplejwt
pip install djangorestframework-simplejwt
配置setting.py
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication' # 使用rest_framework_simplejwt验证身份 ], #权限验证 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated' # 默认权限为验证用户 ], } # simplejwt配置, 需要导入datetime模块 SIMPLE_JWT = { # token有效时长 'ACCESS_TOKEN_LIFETIME': datetime.timedelta(minutes=30), # token刷新后的有效时间 'REFRESH_TOKEN_LIFETIME': datetime.timedelta(days=1), }
配置路由
配置一级路由gadget.urls.py
# 导入 simplejwt 提供的几个验证视图类,这是drf写好的轮子,都不要自己写视图 from rest_framework_simplejwt.views import ( TokenObtainPairView, TokenRefreshView, TokenVerifyView ) urlpatterns = [ #一级路由 path('admin/', admin.site.urls), path('tool/',include('apps.tool.urls')), path('users/',include('apps.users.urls')), # 获取Token的接口 path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), # 刷新Token有效期的接口 path('api/refresh/', TokenRefreshView.as_view(), name='token_refresh'), # 验证Token的有效性 path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'), ]
测试rest_framework_simplejwt自带的token相关接口
测试这三个路由
使用users模型中的数据进行获取token,可以算是登录接口
api/token/
api/refresh/
设置中有设置被刷新的token可以有多长的有效期
api/token/verify/
这个token过了30分钟了失效了
使用token
测试失效的token
测试生效的token
djangorestframework-simplejwt定制
实现登录接口
先写序列化器
from django.contrib.auth import get_user_model from rest_framework import serializers from rest_framework_simplejwt.serializers import TokenObtainPairSerializer # 如果自定义了用户表,那么就要使用这个方法来获取用户模型 # 没有自定义的话可以使用以下方式加载用户模型: # from django.contrib.auth.models import User # 不过这种是万能的 User = get_user_model() # 重写TokenObtainPairSerializer类的部分方法以实现自定义数据响应结构和payload内容 class MyTokenSerializer(TokenObtainPairSerializer): @classmethod def get_token(cls, user): """ 此方法往token的有效负载 payload 里面添加数据 例如自定义了用户表结构,可以在这里面添加用户邮箱,头像图片地址,性别,年龄等可以公开的信息 这部分放在token里面是可以被解析的,所以不要放比较私密的信息 :param user: 用戶信息 :return: token """ token = super().get_token(user) # 添加个人信息 token['name'] = user.username return token def validate(self, attrs): """ 此方法为响应数据结构处理 原有的响应数据结构无法满足需求,在这里重写结构如下: { "refresh": "xxxx.xxxxx.xxxxx", "access": "xxxx.xxxx.xxxx", "expire": Token有效期截止时间, "username": "用户名", "email": "邮箱" } :param attrs: 請求參數 :return: 响应数据 """ # data是个字典 # 其结构为:{'refresh': '用于刷新token的令牌', 'access': '用于身份验证的Token值'} data = super().validate(attrs) # 获取Token对象 refresh = self.get_token(self.user) #加个token的键,值和access键一样 data['token']=data['access'] #然后把access键干掉 del data['access'] # 令牌到期时间 data['expire'] = refresh.access_token.payload['exp'] # 有效期 # 用户名 data['username'] = self.user.username # 邮箱 data['email'] = self.user.email return data
再写视图
from django.contrib.auth import get_user_model from rest_framework import status from rest_framework.response import Response from rest_framework_simplejwt.views import TokenViewBase from .serializers import MyTokenSerializer, RegisterSerializers User = get_user_model() # 自定义的登陆视图 class LoginView(TokenViewBase): serializer_class = MyTokenSerializer # 使用刚刚编写的序列化类 # post方法对应post请求,登陆时post请求在这里处理 def post(self, request, *args, **kwargs): # 使用刚刚编写时序列化处理登陆验证及数据响应 serializer = self.get_serializer(data=request.data) try: serializer.is_valid(raise_exception=True) except Exception as e: raise ValueError(f'验证失败: {e}') return Response(serializer.validated_data, status=status.HTTP_200_OK)
配置二级路由
配置一级路由
测试djangorestframework-simplejwt定制