在Access-Control-Allow-Origin中将通配符用于子域

mod*_*tor 5 ajax xmlhttprequest cors express

我正在为我的网站使用Express并使用凭证xhr。我想请求http://example.com来自http://admin.example.com或者http://service1.example.com,这是我Access-Control-Allow-Origin在Express服务器部分:

// 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();
});
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试从http://admin.example.comhttp://example.com的凭据xhr时,它失败并显示:

提取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
  • [anything] .example.com

我使用XHR的Fetch API,并设置了credentials: true。有什么我想念的吗?任何建议将不胜感激。

Ger*_*bus 5

我同意德里克的评论。另一件事是,源头可以被欺骗,所以这不是一个安全的解决方案。

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()
})
Run Code Online (Sandbox Code Playgroud)


hjp*_*r92 2

首先,IIRC;Express 文档明确要求您不要对中间件使用 lambda 表达式。

谈到 CORS 问题,通配符子域在上下文中无效。该支持是最近添加的(2016 年 5 月),在此之前,CORS 标头必须与域名完全匹配

但是,您可以处理您的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()
})
Run Code Online (Sandbox Code Playgroud)