如何正确配置Access-Control-Allow-Headers处理带凭证的跨域请求?
Django CORS跨域配置问题解答
问题1:同时配置Access-Control-Allow-Credentials = 'true'和Access-Control-Allow-Headers = '*'是否存在安全风险?
首先要明确,这两个配置本身无法同时生效,安全风险的核心不在参数本身,而在跨域源的控制规则:
- 如果你同时开启了允许所有跨域源(django-cors-headers中对应
CORS_ALLOW_ALL_ORIGINS = True) +CORS_ALLOW_CREDENTIALS = True,属于高危配置,任意第三方网站都可以诱导用户发起带身份凭证的请求,窃取用户数据,存在严重CSRF风险。 - 如果你是通过
CORS_ALLOWED_ORIGINS明确指定可信的调用方域名,开启CORS_ALLOW_CREDENTIALS = True没有安全风险。而Access-Control-Allow-Headers只要配置的是业务必需的请求头,也不会引入额外风险。
问题2:是否需要要求调用方禁止携带凭证和自定义头?
如果你的接口本身不需要通过Cookie或自定义请求头做身份校验,调用方携带的凭证和自定义头确实不影响业务逻辑,优先建议让调用方关闭withCredentials配置、移除不必要的自定义头。这种方案配置成本最低,后端直接设置CORS_ALLOW_HEADERS = "*"即可,也不会引入凭证泄漏的潜在风险。如果调用方调整配置的成本过高,或者后续接口有鉴权规划,直接调整后端CORS配置即可,不需要要求调用方修改。
问题3:带凭证的请求下Access-Control-Allow-Headers = '*'是否不生效?
你的理解完全正确。CORS规范明确规定,对于携带凭证的请求(即请求方配置了withCredentials: true的场景),Access-Control-Allow-Headers返回的*不会被当作通配符处理,只会被识别为字面量的*头,无法匹配任何自定义请求头,包括Authorization这类鉴权头必须显式在允许列表中声明,才会被预检请求放行。所以Access-Control-Allow-Credentials = true和Access-Control-Allow-Headers = '*'的组合无法达到预期的放行效果,配置*无效。
正确配置示例(django-cors-headers)
# settings.py # 明确指定允许的跨域源,禁止开启CORS_ALLOW_ALL_ORIGINS CORS_ALLOWED_ORIGINS = [ "https://调用方域名1.com", "https://调用方域名2.com", ] # 开启允许凭证 CORS_ALLOW_CREDENTIALS = True # 显式列出所有允许的请求头,包含对方携带的自定义头 CORS_ALLOW_HEADERS = [ "accept", "accept-encoding", "authorization", "content-type", "dnt", "origin", "user-agent", "x-csrftoken", "x-requested-with", "field_name", # 替换为对方实际携带的自定义请求头名称 ]
内容的提问来源于stack exchange,提问作者JordanGreissman
相关产品推荐
相关产品推荐

