使用Axios调用Django PasswordResetView出现403 CSRF Token错误如何解决
问题解决方法
一、CSRF 403错误规避方案
有两种常用方案可根据你的项目场景选择:
方案1:配置Axios自动携带CSRF Token(推荐,安全性更高)
- 先修改Django的
settings.py配置,允许JS读取CSRF Cookie:
# settings.py CSRF_COOKIE_HTTPONLY = False # 如果前后端跨域,还要额外加以下配置 CSRF_TRUSTED_ORIGINS = ["https://你的前端域名", "http://localhost:8080"] # 替换成你前端的实际地址 CORS_ALLOW_CREDENTIALS = True
- 在Vue项目的全局Axios配置中添加以下规则(一般是main.js或者单独的axios封装文件里):
import axios from 'axios' // 配置axios自动从cookie读取csrftoken并添加到请求头 axios.defaults.xsrfCookieName = 'csrftoken' axios.defaults.xsrfHeaderName = 'X-CSRFToken' // 跨域场景下要开启携带凭证 axios.defaults.withCredentials = true
配置完成后所有Axios的POST请求都会自动带上CSRF Token,不会再报403错误。
方案2:给密码重置接口豁免CSRF校验
如果你的密码重置接口是公开无登录态的,也可以直接给这个接口关闭CSRF检查:
修改Django的urls.py,用csrf_exempt装饰器包裹ResetPasswordView:
from django.urls import path from django.contrib.auth.views import PasswordResetView from django.views.decorators.csrf import csrf_exempt urlpatterns = [ # 其他接口... path('api/v1/accounts/password_reset/', csrf_exempt(PasswordResetView.as_view()), name='password_reset'), ]
二、前后端分离下Vue+Django实现密码重置的最佳方案
Django原生的Password系列视图默认是绑定模板渲染的,不适合前后端分离场景,推荐按以下逻辑改造:
1. Django端改造
- 重写
PasswordResetView的响应逻辑,替换模板渲染为JSON响应:
from django.contrib.auth.views import PasswordResetView from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator @method_decorator(csrf_exempt, name='dispatch') class CustomPasswordResetView(PasswordResetView): # 自定义邮件模板,把重置链接指向你的Vue前端地址 html_email_template_name = 'registration/password_reset_email.html' subject_template_name = 'registration/password_reset_subject.txt' def form_valid(self, form): # 原生逻辑:发送重置邮件 form.save( request=self.request, use_https=self.request.is_secure(), # 可以在这里指定自定义的邮件发送逻辑 ) # 返回JSON响应而不是跳转 return JsonResponse({"status": "success", "msg": "重置邮件已发送,请查收"}) def form_invalid(self, form): # 表单验证失败(比如邮箱不存在、格式错误)返回错误信息 return JsonResponse({"status": "error", "msg": form.errors}, status=400)
- 自定义邮件模板里的重置链接,格式改为你的Vue前端地址,比如:
请点击以下链接重置密码: https://你的前端域名/reset-confirm?uid={{uid}}&token={{token}}
- 同理重写
PasswordResetConfirmView,用来处理前端提交的新密码、uid和token,同样返回JSON响应。
2. Vue端逻辑
- 现有重置密码页面提交邮箱后,根据Django返回的结果提示用户,成功则跳转到登录页,失败则展示对应错误信息。
- 新增重置密码确认页面,读取url里的
uid和token参数,用户输入新密码后提交到改造后的PasswordResetConfirmView接口,验证通过后跳转到登录页。
优化方案:直接使用成熟的第三方库
如果不想自己改造原生视图,推荐直接使用dj-rest-auth这类Django REST Framework生态的账户管理库,已经内置了标准化的密码重置、确认等JSON接口,无需自己重写视图,只需要配置前端域名即可直接对接Vue前端,开发效率更高。
内容的提问来源于stack exchange,提问作者Ivan Stepanchuk
相关产品推荐
相关产品推荐

