解决dj-rest-auth发送无效密码重置链接问题
问题原因及修复方案
核心原因
你混淆了Django原生认证视图和dj-rest-auth提供的视图,两者的密码重置token生成/验证逻辑不兼容。如果发起重置请求用的是dj-rest-auth的接口,却用原生视图处理链接验证,必然会出现链接无效的错误。
修复步骤
1. 统一使用dj-rest-auth的密码重置流程
如果项目主要基于DRF和dj-rest-auth,建议完全使用它的密码重置视图,避免混用:
修改api/urls.py,启用dj-rest-auth的密码重置路由:
app_name = 'api' from dj_rest_auth.views import PasswordResetView, PasswordResetConfirmView router = routers.DefaultRouter() router.register(r'users', UserViewSet, basename='user') urlpatterns = [ path('', include(router.urls)), path('dj-rest-auth/', include('dj_rest_auth.urls')), path('dj-rest-auth/registration/', include('dj_rest_auth.registration.urls')), path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), # 启用dj-rest-auth的密码重置视图 path('password-reset/', PasswordResetView.as_view(), name='password_reset'), path('password-reset-confirm/<uidb64>/<token>/', PasswordResetConfirmView.as_view(), name='password_reset_confirm'), ]
配置邮件链接与跳转(可选)
在settings.py中指定邮件链接的域名和跳转逻辑:
# 替换为你的实际域名 DOMAIN = "your-domain.com" SITE_NAME = "你的站点名称" REST_AUTH = { # 重置成功后跳转的前端页面(前后端分离场景) 'PASSWORD_RESET_CONFIRM_URL': '/password-reset-confirm/{uidb64}/{token}/', }
2. 若坚持使用Django原生auth视图
如果必须用原生视图处理,需确保请求发起与验证流程统一:
确保根路由包含users应用的命名空间
在项目根urls.py中添加:
urlpatterns = [ ... path('users/', include('users.urls')), ... ]
修正邮件模板的链接命名空间
在users/templates/users/password_reset_email.html中,确保链接使用正确的命名空间:
{% autoescape off %} 点击下方链接重置密码: {{ protocol }}://{{ domain }}{% url 'users:password_reset_confirm' uidb64=uid token=token %} 若无法点击,请复制链接到浏览器地址栏打开。 {% endautoescape %}
3. 排查其他潜在问题
- token过期:检查
settings.py中PASSWORD_RESET_TIMEOUT(默认1小时),若链接生成后超时会失效。 - 链接完整性:确认邮件中的
uidb64和token未被截断。 - 自定义用户模型:如果自定义了User模型,需确保继承
AbstractBaseUser并正确实现get_username()方法,否则token验证会失败。
内容的提问来源于stack exchange,提问作者A_K
相关产品推荐
相关产品推荐

