在Django中记录JWT刷新时间的技术问题
问题分析
authenticate返回None的原因:- 首先检查
AUTHENTICATION_BACKENDS配置是否已添加你的CustomAuthenticationBackend,未配置的话Django不会启用自定义后端。 - 其次,
super().authenticate(request, username, password)返回None意味着用户名密码验证失败,或者请求未正确传递username/password参数(Djoser的/jwt/auth默认从request.data取这两个参数,参数名不匹配也会导致验证失败)。 - 你的
try-except块位置不合理:super().authenticate返回None不会触发User.DoesNotExist异常,这个捕获逻辑无效。
- 首先检查
JWT刷新请求的用户获取逻辑:
Djoser的/jwt/refresh端点由RefreshTokenView处理,核心流程是:
- 解析请求中的refresh token
- 从token的payload中提取用户ID
- 通过
get_user方法调用UserModel.objects.get(pk=user_id)获取用户对象 - 验证token有效性后生成新的access token返回
解决方案
方案1:修复自定义认证后端,适配/jwt/auth端点
先确保配置正确,再修正认证逻辑:
- 在
settings.py中添加自定义后端:
AUTHENTICATION_BACKENDS = [ 'yourapp.backends.CustomAuthenticationBackend', 'django.contrib.auth.backends.ModelBackend', ]
- 修正
CustomAuthenticationBackend代码(使用Django时区工具,调整逻辑):
from django.utils import timezone from django.contrib.auth.backends import ModelBackend class CustomAuthenticationBackend(ModelBackend): def authenticate(self, request, username=None, password=None): user = super().authenticate(request, username, password) if user is not None: user.last_login = timezone.now() user.save() return user
方案2:重写RefreshTokenView,处理JWT刷新时的用户信息更新
如果需要在刷新token时更新用户时间戳,可以自定义视图替换Djoser的默认端点:
- 在
yourapp/views.py中创建自定义视图:
from django.utils import timezone from djoser.views import RefreshTokenView class CustomRefreshTokenView(RefreshTokenView): def post(self, request, *args, **kwargs): response = super().post(request, *args, **kwargs) user = self.request.user if user.is_authenticated: # 可更新自定义时间戳字段,或覆盖last_login(注意Django默认登录时会自动更新) user.last_login = timezone.now() user.save() return response
- 在项目
urls.py中替换Djoser的刷新端点(需放在include('djoser.urls.jwt')之前):
from django.urls import path, include from yourapp.views import CustomRefreshTokenView urlpatterns = [ path('auth/jwt/refresh/', CustomRefreshTokenView.as_view(), name='jwt-refresh'), path('auth/', include('djoser.urls.jwt')), # 其他路由 ]
内容的提问来源于stack exchange,提问作者pyg
相关产品推荐
相关产品推荐

