Django drf基于rest_framework_simplejwt实现登陆获取token、校验token、刷新token有效期
安装rest_framework_simplejtw
配置settings.py
配置路由
测试rest_framework_simplejwt自带token相关接口
使用token
djangorestframework-simplejwt定制
测试djangorestframework-simplejwt定制
安装rest_framework_simplejwt
pip install djangorestframework-simplejwt
配置settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
# 默认所有接口都需要token认证
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
# simplejwt 认证
'rest_framework_simplejwt.authentication.JWTAuthentication',
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
)
INSTALLED_APPS = [
'rest_framework',
# 引入token认证
'rest_framework.authtoken',
]
JWT_AUTH = {
# token有效期
'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300),
# token刷新后的有效时间
'REFRESH_TOKEN_LIFETIME': datetime.timedelta(minutes=30),
}
}
配置路由
# rest_framework_simplejwt 提供的现成视图类
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
TokenVerifyView,
)
urlpatterns = [
path('admin/', admin.site.urls),
# JTW认证接口
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
# 刷新JWT有效期接口
path('api/refresh', TokenObtainPairView.as_view(), name='token_refresh'),
# 验证token有效期接口
path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify')
]
测试rest_framework_simplejwt自带token相关接口
获取token接口
刷新token有效期接口
验证token有效期接口
使用token
测试失效的token
测试生效的token
djangorestframework-simplejwt定制
目标:实现登陆接口 先写序列化器from django.contrib.auth import get_user_model
from rest_framework.serializers import ModelSerializer
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
# 重写了User模型,所以通过get_user_model获取User模型对象
User = get_user_model()
# 重写TokenObtainPairSerializer类的部分方法以实现自定义数据响应结构和payload
class MyTokenSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
"""
往token有效负载payload里添加数据
"""
token = super().get_token(user)
token['name'] = user.username
return token
def validate(self, attrs):
"""
响应数据结构处理重写为以下结构
{
"refresh": "...",
"access": "...",
"expire": 有效期时间戳,
"username": "...",
"email": "..."
}
"""
# data是个字典
# 其结构为:{'refresh': '用于刷新token的令牌', 'access': '用于身份验证的Token值'}
data = super().validate(attrs)
# 获取token对象
refresh = self.get_token(self.user)
# 修改原data对象的键access为token
data['token'] = data['access']
# 删除data对象的access键
del data['access']
# 增加有效期信息
data['expire'] = refresh.access_token.payload['exp']
# 增加用户名信息
data['username'] = self.user.username
# 增加email信息
data['email'] = self.user.email
return data
再写视图类
from .serializers import MyTokenSerializer
from rest_framework import status
from rest_framework.response import Response
from rest_framework_simplejwt.views import TokenViewBase
# Create your views here.
class LoginView(TokenViewBase):
serializer_class = MyTokenSerializer
# 暂时只写了正确用户名和密码的处理逻辑
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)
注册一级路由
urlpatterns = [
path('admin/', admin.site.urls),
# 用户登陆接口
path('api/users/', include('users.urls')),
# JTW认证接口
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
# 刷新JWT有效期
path('api/token/refresh/', TokenObtainPairView.as_view(), name='token_refresh'),
# 验证token有效期接口
path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
path('api/book/', BookView.as_view(), name='book')
]
注册二级路由
from django.urls import path
from .views import LoginView
urlpatterns = [
path('login/', LoginView.as_view(), name="login")
]