Django+React Native登出后无法再次登录的403权限问题求助
解决Django + React Native登录后登出再登录403 Forbidden问题
核心问题分析
首次登录正常,仅前端导航登出后再次登录触发403,大概率是前端登出不彻底导致后端残留认证状态,或请求头携带无效认证信息触发Django的权限校验。
具体解决思路
1. 完善前端登出逻辑,清除所有认证相关数据
当前前端仅通过导航切换页面,未清理任何认证存储或请求头信息:
- 若使用Session认证:需清除Django设置的
sessionid和csrftokenCookie(可借助react-native-cookies库),同时清除AsyncStorage中存储的用户信息。 - 若使用JWT/Token认证:需移除AsyncStorage中的token,并重置axios的默认请求头。
示例修复后的登出逻辑:
// 导入依赖(若用cookie) import CookieManager from '@react-native-cookies/cookies'; const handleLogout = async () => { // 清除AsyncStorage中的用户数据 await AsyncStorage.removeItem('username'); await AsyncStorage.removeItem('authToken'); // 若存储了token // 清除Cookie(针对Session认证) await CookieManager.clearAll(); // 重置axios默认请求头(针对Token认证) axios.defaults.headers.common['Authorization'] = ''; // 导航回登录页 navigation.navigate('Login'); };
2. 确保后端登录接口的权限配置正确
检查Django的mobile-login视图:
- 若接口是公开的登录接口,需添加
@csrf_exempt装饰器(或在urls.py中用csrf_exempt包裹),避免CSRF校验拦截未携带有效CSRF token的请求。 - 确认视图未添加不必要的权限装饰器(如
@login_required),登录接口本身应该允许未认证用户访问。
示例Django视图调整:
from django.views.decorators.csrf import csrf_exempt from django.http import JsonResponse @csrf_exempt def mobile_login(request): # 登录逻辑代码 if request.method == 'POST': # 处理登录请求 return JsonResponse({'status': 'success'})
3. 前端登录请求携带正确的CSRF Token(若启用CSRF中间件)
如果Django启用了CsrfViewMiddleware,前端登录请求需要携带CSRF Token:
- 首次登录时,Django会返回
csrftokenCookie,后续请求需将其放入X-CSRFToken请求头。 - 可以在axios请求中自动获取并携带CSRF Token:
// 在登录请求前获取CSRF Token import CookieManager from '@react-native-cookies/cookies'; const handleLogin = async () => { const cookies = await CookieManager.get('https://8d16-103-62-155-152.ngrok-free.app'); const csrfToken = cookies.csrftoken?.value; axios.post('https://8d16-103-62-155-152.ngrok-free.app/api/auth/mobile-login/', { username, password }, { headers: { 'X-CSRFToken': csrfToken } } ) .then(response => { // 存储必要的用户信息 await AsyncStorage.setItem('username', username); navigation.navigate('Main'); }) .catch(error => { Alert.alert('Login Failed', error.response?.data?.detail || 'Invalid username or password'); }); };
4. 调用后端登出接口销毁服务器端Session
若后端提供登出接口,前端登出时应主动调用该接口,让Django销毁服务器端的Session数据,避免旧Session残留导致权限校验异常:
const handleLogout = async () => { try { // 调用后端登出接口 await axios.post('https://8d16-103-62-155-152.ngrok-free.app/api/auth/logout/'); } catch (err) { // 忽略登出接口失败,继续清理前端数据 } // 后续清理前端数据和导航逻辑 await AsyncStorage.removeItem('username'); await CookieManager.clearAll(); navigation.navigate('Login'); };
5. 调试请求细节定位问题
- 使用RN调试工具查看第二次登录请求的请求头和Cookie,对比首次登录的请求差异,确认是否携带了无效的认证信息。
- 在Django端开启DEBUG模式,查看403错误的具体原因(CSRF验证失败/权限不足),可在视图中打印
request.META或查看Django的详细日志。
内容的提问来源于stack exchange,提问作者Isaac Llenas
相关产品推荐
相关产品推荐

