React使用Fetch API向Django发送CSRF Token时出现403错误排查
CSRF Token验证失败导致403 Forbidden问题排查
代码与问题描述
我生成CSRF Token的代码如下:
const [cr , setCR] = useState('') const getcsrf = async () => { await fetch('http://localhost:8000/auth/gettoken') .then( async res => await res.json()).then(data =>{ setCR( data.crsftoken) console.log(cr) }) } useEffect( () => { getcsrf() },[] )
获取到Token后,通过Fetch发送登录请求的代码:
const handlelogin = async () => { if(cr !== ''){ console.log(cr) await fetch('http://localhost:8000/auth/login', { method : "POST", credentials: "include" , headers: { "Content-Type": "application/json", "X-CSRFToken" : cr }, body : { "username" : username, "password" : password } } ).catch(err => console.log(err)) } else { console.log('cr is null') } }
目前的问题是:CSRF Token能正常生成并通过console.log输出,但发送请求后返回403 Forbidden错误,日志显示:
Forbidden (CSRF token from the 'X-Csrftoken' HTTP header incorrect.): /auth/login [09/Nov/2023 05:49:59] "POST /auth/login HTTP/1.1" 403 2553
我需要成功发送该POST请求,请问问题出在哪里?
可能的问题点与解决建议
- 状态更新的异步特性:
setCR是异步操作,在getcsrf的then里立刻console.log(cr),打印的是更新前的旧值。你可以在handlelogin里打印的cr和后端生成的Token做对比,确认是否是正确的值。 - 请求Body未序列化:Fetch要求
body必须是JSON字符串,你直接传了JS对象,需要用JSON.stringify()转换,改成:
后端如果解析不到正确参数,可能触发CSRF验证逻辑异常。body: JSON.stringify({ username, password }) - Token字段名拼写错误:检查后端返回的Token字段名是不是
crsftoken(有没有少写字母?比如应该是csrftoken),如果字段名不匹配,cr拿到的就是错误值。 - Cookie与Header Token不匹配:CSRF验证通常要求Header里的Token和Cookie中的Token一致。确认获取Token的请求是否已经把Token写入Cookie,且登录请求携带的Cookie和Header里的Token是同一个值。
- Header大小写问题:错误日志里提到的是
X-Csrftoken,你的代码里写的是X-CSRFToken。虽然HTTP Header本身大小写不敏感,但部分后端框架可能严格匹配,建议改成和日志一致的X-Csrftoken试试。
内容的提问来源于stack exchange,提问作者Tahir Mansour
相关产品推荐
相关产品推荐

