在 Access-Control-Allow-Origin 中使用通配符作为子域
Posted
技术标签:
【中文标题】在 Access-Control-Allow-Origin 中使用通配符作为子域【英文标题】:Using wildcard for subdomain in Access-Control-Allow-Origin 【发布时间】:2017-03-05 20:54:30 【问题描述】:我在我的网站上使用 Express 并使用凭据 xhr。我想从http://admin.example.com
或http://service1.example.com
向http://example.com
请求,这是我在快递服务器中的Access-Control-Allow-Origin
部分:
// CORS
app.use((req, res, next) =>
res.setHeader('Access-Control-Allow-Origin', 'http://*.example.com');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE');
next();
);
但是当我尝试从 http://admin.example.com 到 http://example.com 的凭证 xhr 时,它失败了:
Fetch API 无法加载
http://example.com/api/v1/authentication/signin
。 对预检请求的响应未通过访问控制检查: 'Access-Control-Allow-Origin
' 标头有一个值 'http://*.example.com
' 这不等于提供的来源。起源 'http://admin.example.com' 因此不允许访问。有 服务器发送带有有效值的标头,或者,如果响应不透明 满足您的需求,将请求的模式设置为“no-cors”以获取 禁用 CORS 的资源。
看起来是因为浏览器不明白*.example.com
到底是什么意思,拒绝请求。
我想从这些域中请求:
example.com admin.example.com service1.example.com service2.example.com [任何东西].example.com我正在为 XHR 使用 Fetch API,并设置 credentials: true
。有什么我错过的吗?任何建议都会非常感激。
【问题讨论】:
【参考方案1】:我同意 Derric 的评论。另一件事是原始标头可以被欺骗,所以这不是一个安全的解决方案。
app.use(function (req, res, next)
if (req.headers.origin.endsWith('example.com'))
res.setHeader('Access-Control-Allow-Origin', 'http://' + req.headers.origin)
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type')
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE')
next()
)
【讨论】:
【参考方案2】:首先,IIRC;快递文件明确要求您不要使用 中间件的 lambda 表达式。
谈到 CORS 问题,通配符子域在上下文中无效。该支持是最近添加的(在 May '16 中),直到那时,the CORS header must be an exact match of the domain name。
但是,您可以处理您的 req.hostname
值并将其添加到响应标头中:
// CORS
app.use(function (req, res, next)
if (req.hostname.endsWith('example.com'))
res.setHeader('Access-Control-Allow-Origin', 'http://' + req.hostname)
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type')
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE')
next()
)
【讨论】:
我会调整它以不使用主机名,而您应该使用Origin
标头。在您的情况下,主机名将是 example.com,但来源将是 admin.example.com。 Origin 需要匹配确切的协议和域(如果是非标准端口,还需要匹配端口)。更多信息:moesif.com/blog/technical/cors/…【参考方案3】:
在此处添加另一个小调整。我们还应该考虑“协议”:
app.use(function (req, res, next)
if (req.headers.origin.endsWith('example.com'))
res.setHeader('Access-Control-Allow-Origin', req.protocol + '://' + req.headers.origin)
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type')
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE')
next()
)
【讨论】:
以上是关于在 Access-Control-Allow-Origin 中使用通配符作为子域的主要内容,如果未能解决你的问题,请参考以下文章