通过ngrok连接Django应用时Cookie未设置引发403权限问题
我之前也踩过这个一模一样的坑!本地用localhost跑Session认证顺得很,一换ngrok的临时域名就直接403,折腾半天才搞明白——核心是浏览器的跨站点Cookie安全策略和Django默认的Cookie配置不匹配,下面给你一步步捋清楚解决办法:
1. 调整Django的Cookie核心配置
Django默认的Session和CSRF Cookie只绑定当前域名,而且SameSite属性默认是Lax,这在跨域名的ngrok场景下会被浏览器拦截。你需要在settings.py里修改这些配置:
# 让Cookie适配所有ngrok子域名(不管你的ngrok域名是xxx.ngrok.io还是yyy.ngrok.io都能生效) SESSION_COOKIE_DOMAIN = '.ngrok.io' CSRF_COOKIE_DOMAIN = '.ngrok.io' # 跨站点请求需要放宽SameSite限制,同时必须开启Secure(ngrok默认是HTTPS,符合要求) SESSION_COOKIE_SAMESITE = 'None' CSRF_COOKIE_SAMESITE = 'None' SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True
要是你的前端也部署在ngrok域名下,那可以不用设置
_DOMAIN参数,只调整SameSite和Secure就行。
2. 给Axios开启Cookie携带权限
前端用axios发请求时,必须手动开启withCredentials,否则浏览器不会主动把Cookie带到跨域的后端:
// 全局配置(所有请求都生效) axios.defaults.withCredentials = true; // 或者单个请求单独设置 axios.get('/api/profile', { withCredentials: true })
3. 手动处理CSRF Token的传递(关键!)
跨域场景下,浏览器不会自动把CSRF Token的Cookie放到请求头里,所以得手动走这一步:
3.1 后端加个获取CSRF Token的接口
在你的views里加个简单视图:
from django.middleware.csrf import get_token from rest_framework.decorators import api_view from rest_framework.response import Response @api_view(['GET']) def get_csrf_token(request): return Response({'csrfToken': get_token(request)})
然后在urls.py里配个路由:
path('api/get-csrf-token/', get_csrf_token, name='get_csrf_token'),
3.2 前端获取并携带Token
在发送登录、获取Profile这类请求前,先调用上面的接口拿到CSRF Token,再放到请求头里:
// 先获取CSRF Token axios.get('https://你的ngrok域名/api/get-csrf-token/', { withCredentials: true }) .then(response => { const csrfToken = response.data.csrfToken; // 把Token设为axios默认请求头 axios.defaults.headers.common['X-CSRFToken'] = csrfToken; // 之后再发登录、获取Profile的请求 axios.post('https://你的ngrok域名/api/login/', { username: 'xxx', password: 'xxx' }, { withCredentials: true }) .then(() => { axios.get('https://你的ngrok域名/api/profile/', { withCredentials: true }) .then(res => console.log(res.data)); }); });
4. 验证配置是否生效
打开浏览器F12开发者工具:
- 切到Application标签,看看Cookies里有没有
sessionid和csrftoken,域名是不是.ngrok.io - 切到Network标签,检查请求头里是否同时携带了
Cookie和X-CSRFToken
要是这些都正常,再访问你的ProfileAPI端点就不会返回403了!
内容的提问来源于stack exchange,提问作者shailysangwan
相关产品推荐
相关产品推荐

