使用vue-recaptcha搭配DRF中间件时出现CSRF token missing错误
问题根因
该问题是Django CSRF校验规则、Cookie生成时序、跨域HTTPS配置共同作用的结果,对应你的三个疑问逐一解释:
1. 本地环境不触发问题的原因
Django对localhost/127.0.0.1等本地回环地址有CSRF校验兼容逻辑,且本地开发通常开启了CORS_ALLOW_ALL_ORIGINS、DEBUG = True等调试配置,会放松CSRF校验规则。
生产环境你开启了HTTPS,且大概率设置了CSRF_COOKIE_SECURE = True,会强制CSRF Cookie仅通过HTTPS传输,同源校验也更严格,本地HTTP环境不会触发该规则。
2. 勾选顺序影响结果的原因
Google Recaptcha V2在勾选时会触发校验请求:
- 先勾选用户协议再勾选Recaptcha:用户协议勾选触发了前端表单校验逻辑,你前端大概率在表单校验时已经获取了CSRF Token写入axios请求头,后续Recaptcha校验请求携带了正确的CSRF Token,因此请求正常。
- 先勾选Recaptcha再勾选用户协议:Recaptcha校验请求发起时,前端还没有获取CSRF Token,Django在校验完Recaptcha返回响应时,会自动种下新的CSRF Cookie,但你的axios没有自动更新请求头里的CSRF Token值,后续提交表单时携带的还是空的/旧的CSRF Token,触发403错误。
错误触发后,当前Session会被Django标记为CSRF校验失败,后续同一Session的所有请求都会被拦截,因此之后无论调整勾选顺序都会报错。
3. 仅注册表单出现问题的原因
登录、普通数据提交等表单,要么是你在访问对应页面时就已经提前请求了CSRF Token写入请求头,要么是对应视图你已经配置了CSRF豁免(比如登录接口通常会豁免CSRF,因为登录前没有有效Session)。
而注册页面的Recaptcha校验接口你没有配置CSRF豁免,且只有注册页面会触发Recaptcha的异步校验逻辑,才会出现此时序冲突。
修复方案
方案1(推荐):给Recaptcha校验接口豁免CSRF
该接口仅校验Recaptcha Token,不存在修改用户数据的风险,直接豁免CSRF即可解决问题:
from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator @method_decorator(csrf_exempt, name='dispatch') class RecaptchaVerifyView(APIView): allowed_methods = ["POST"] # 其余原有代码保持不变
方案2:调整前端axios配置,自动携带最新CSRF Token
如果不想豁免CSRF,给axios加全局配置,每次请求自动读取Cookie里的最新CSRF Token放入请求头:
axios.defaults.withCredentials = true axios.defaults.xsrfCookieName = 'csrftoken' axios.defaults.xsrfHeaderName = 'X-CSRFToken'
额外生产配置检查
确保Django配置的CSRF_TRUSTED_ORIGINS中包含你的前端域名:
CSRF_TRUSTED_ORIGINS = [ "https://你的前端域名", # 子域名可配置为 "https://*.你的域名.com" ]
内容的提问来源于stack exchange,提问作者Beinje
相关产品推荐
相关产品推荐

