【问题标题】:Using wildcard for subdomain in Access-Control-Allow-Origin在 Access-Control-Allow-Origin 中使用通配符作为子域
【发布时间】:2017-03-05 20:54:30
【问题描述】:

我在我的网站上使用 Express 并使用凭据 xhr。我想从http://admin.example.comhttp://service1.example.comhttp://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.comhttp://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。有什么我错过的吗?任何建议都会非常感激。

【问题讨论】:

    标签: ajax express xmlhttprequest cors


    【解决方案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()
      })
      

      【讨论】:

        猜你喜欢
        • 2012-12-09
        • 2011-09-02
        • 2011-07-28
        • 1970-01-01
        • 2017-01-17
        • 2016-08-03
        • 2019-02-15
        相关资源
        最近更新 更多