ReactJS使用fetch在桌面浏览器正常,iOS Safari返回403未提供认证凭证错误
iOS端Django接口403错误解决方案
以下是按优先级从高到低的可落地排查修复方案:
1. 显式配置fetch请求的凭证携带规则
iOS端所有浏览器均基于WebKit内核,其fetch API默认的credentials配置为omit(即不发送Cookie、HTTP认证等凭证信息),和安卓/桌面Chromium内核浏览器的默认行为不一致,是最常见的触发原因。
修复方式:所有API请求的fetch配置中显式添加credentials: 'include':
// 修正后的fetch请求示例 fetch('https://你的API域名/接口路径', { method: 'GET', // 或POST/PUT等其他请求方法 credentials: 'include', // 必须显式添加该配置 headers: { 'Content-Type': 'application/json' // 其他自定义请求头 }, // body等其他配置项 })
2. 修正Django CORS配置
如果已经添加了上述配置还是报错,检查Django的django-cors-headers配置是否符合要求:
- 必须设置
CORS_ALLOW_CREDENTIALS = True,允许跨域请求携带凭证 - 禁止使用
CORS_ALLOW_ALL_ORIGINS = True,该配置和允许携带凭证规则互斥,需要用CORS_ORIGIN_WHITELIST显式添加你的前端域名:# settings.py示例配置 CORS_ALLOW_CREDENTIALS = True CORS_ORIGIN_WHITELIST = [ 'https://你的前端域名', # 开发环境的话加http://localhost:3000等本地地址 ] - 如果请求带自定义请求头(比如
X-CSRFToken),需要将请求头加入允许列表:CORS_ALLOW_HEADERS = [ 'content-type', 'x-csrftoken', # 其他你用到的自定义请求头 ]
3. 修正Cookie的SameSite与Secure属性
iOS 13及以上版本的Safari对Cookie的SameSite规则校验更严格,跨域场景下需要调整Django的Cookie配置:
# settings.py 新增配置 # 跨域场景下SameSite必须设为None SESSION_COOKIE_SAMESITE = 'None' CSRF_COOKIE_SAMESITE = 'None' # SameSite为None的Cookie必须标记为Secure,仅在HTTPS环境下传输 SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True
注意:该配置要求前后端都必须使用HTTPS协议,开发环境可以临时把上述属性改回
Lax和False测试。
4. 规避iOS智能跟踪预防(ITP)拦截
如果前后端部署在不同根域名下,iOS的ITP策略会把后端域名的Cookie判定为第三方Cookie直接拦截,这种场景下唯一稳定的解决方案是将前后端部署到同一个根域名下,比如:
- 前端地址:
app.你的域名.com - 后端地址:
api.你的域名.com
5. 检查CSRF Token携带逻辑
Django的POST/PUT等非幂等请求默认需要携带CSRF Token,需要确保你在请求头中正确携带了该字段,示例代码如下:
// 从Cookie中提取CSRF Token的工具函数 const getCsrfToken = () => { const value = `; ${document.cookie}`; const parts = value.split(`; csrftoken=`); if (parts.length === 2) return parts.pop().split(';').shift(); } // POST请求示例 fetch('https://你的API域名/接口路径', { method: 'POST', credentials: 'include', headers: { 'X-CSRFToken': getCsrfToken(), 'Content-Type': 'application/json' }, body: JSON.stringify(请求参数) })
临时排查验证方法
可以先在iOS设备的「设置 - Safari浏览器 - 隐私与安全性」中,临时关闭「阻止跨站跟踪」「阻止所有Cookie」两个选项,再测试接口是否正常,如果关闭后请求成功,即可确认是Cookie相关的规则拦截问题,按上述方案调整配置即可。
内容的提问来源于stack exchange,提问作者Dayvvo
相关产品推荐
相关产品推荐

