React Native对接Django API时登出请求报"X-Csrftoken HTTP header has incorrect length"错误的解决方法
React Native对接Django API时登出请求报"X-Csrftoken HTTP header has incorrect length"错误的解决方法
兄弟,我仔细看了你的代码,这个错误的根源其实很好找——你在存储CSRF Token和Session ID的时候多做了一步不必要的JSON.stringify,导致取出来的值带上了额外的双引号,Django验证CSRF Token长度时自然就不通过了!
一、错误原因分析
你看登录代码里的setSessionId和setCsrfToken函数,把本来就是字符串类型的data.sessionid和data.csrftoken用JSON.stringify转了一遍再存到AsyncStorage里。举个例子:
原本的CSRF Token是:
IRFxHgM5LYbhPYNXWHqghBK7IETPnxDEx0TYp4loWKpxcj3DStLTLIhBmAl58VOw
经过JSON.stringify之后就变成了:
"IRFxHgM5LYbhPYNXWHqghBK7IETPnxDEx0TYp4loWKpxcj3DStLTLIhBmAl58VOw"
多了首尾的双引号,长度直接增加了2位,Django的CSRF验证逻辑会检查Token长度是否符合规范,自然就抛出了"X-Csrftoken HTTP header has incorrect length"的错误。
另外还有个小问题:Django默认是通过Cookie传递Session ID的,而不是你用的Authorization头,这也可能导致登出时Session无法被正确识别。
二、具体修复步骤
1. 修正登录时的存储逻辑
去掉多余的JSON.stringify,直接存储原始字符串值即可:
const setSessionId = async (value) => { try { // 去掉JSON.stringify,直接存原始字符串 await AsyncStorage.setItem('sessionid', value) } catch(e) { console.log(e) } } const setCsrfToken = async (value) => { try { // 同样去掉JSON.stringify await AsyncStorage.setItem('csrftoken', value) } catch(e) { console.log(e) } }
2. 修正登出请求的Header配置
把Session ID放到Cookie头里(符合Django默认的Session机制),同时确保CSRF Token是原始值:
const postRequestLogout = async () => { try { const sessionid_value = await AsyncStorage.getItem('sessionid') const csrftoken_value = await AsyncStorage.getItem('csrftoken') console.log("Session: ", sessionid_value) console.log("Csrf: ", csrftoken_value) // 这里要确认输出没有多余的双引号 const requestOptions = { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFTOKEN': csrftoken_value, // 将Session ID放入Cookie头 'Cookie': `sessionid=${sessionid_value}` } } const response = await fetch( 'http://myIP/user_account/api_logout_user_account/', requestOptions ) const data = await response.json() Alert.alert("Success"); console.log(data) } catch(e) { console.log(e) } }
3. 清理旧的错误存储值(可选)
如果你之前已经存了带双引号的Token,最好先清理一下AsyncStorage,避免旧值干扰:
// 可以在登录前或者App启动时执行一次清理 await AsyncStorage.removeItem('sessionid'); await AsyncStorage.removeItem('csrftoken');
三、额外验证点
- 调试时打印
csrftoken_value,确认输出的是不带双引号的原始Token字符串; - 确认Django的CSRF中间件已正确配置,API视图未使用
csrf_exempt装饰器(api_view默认会对POST请求检查CSRF); - 确保Django后端配置了CORS允许携带Cookie和自定义Header(如果用了
django-cors-headers,需设置CORS_ALLOW_CREDENTIALS = True)。
内容来源于stack exchange




