NodeJS - CORS中间件`origin`未定义

Posted

技术标签:

【中文标题】NodeJS - CORS中间件`origin`未定义【英文标题】:NodeJS - CORS middleware `origin` undefined 【发布时间】:2017-07-24 05:06:46 【问题描述】:

我有一个使用cors npm 包作为中间件的应用程序。我是这样设置的:

  if(process.env.NODE_ENV === 'production') 
    var whitelist = ['http://mywebsite.com', 'https://mywebsite.com']
    var corsOptions = 
      origin: (origin, callback) => 
          var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
          console.log('ORIGIN: ', origin);  // => undefined
          callback(originIsWhitelisted ? null : 'Bad Request', originIsWhitelisted)
      ,
      credentials:true
    
    app.use(cors(corsOptions));
  

我的 corsOptions 中的origin 参数是undefined。为什么会这样,我该如何解决?

【问题讨论】:

github.com/expressjs/cors/issues/71 【参考方案1】:

如果您不想阻止 REST 工具或服务器到服务器的请求,请在源函数中添加 !origin 检查,如下所示:

var corsOptions = 
  origin: function (origin, callback) 
    if (!origin || whitelist.indexOf(origin) !== -1) 
      callback(null, true)
     else 
      callback(new Error('Not allowed by CORS'))
    
  

【讨论】:

由于它的未定义如果相同的来源,那么检查它而不是仅仅检查一个虚假的值不是很有意义吗? origin === undefined 在生产中使用if (!origin) 时存在一个安全问题:许多渗透测试脚本没有设置origin,因此它们的请求将通过此CORS 测试。我的生产服务器收到了数千个渗透测试请求,直到我剥离了if(!origin) 测试。【参考方案2】:

当您在调用 API 的同一源中加载页面时,就会发生这种情况。除非 API 调用的域与提供页面的域不同,否则浏览器不会设置“Origin”标头。

这里有进一步的解释https://github.com/expressjs/cors/issues/113

如果您使用浏览器控制台从不同的网站进行 API 调用,您会看到浏览器设置了 Origin 标头,因此在 express 读取时不会未定义。

您可以使用

if (whitelist.indexOf(origin) !== -1 || !origin) 

【讨论】:

【参考方案3】:

use 是一种配置中间件的方法。您必须仅在路由中应用 corsoptions。这是我根据文档看到的。还没有测试它。希望对你有帮助。

var whitelist = ['http://example1.com', 'http://example2.com']
var corsOptions = 
  origin: function (origin, callback) 
    var originIsWhitelisted = whitelist.indexOf(origin) !== -1
    callback(originIsWhitelisted ? null : 'Bad Request', originIsWhitelisted)
  


app.get('/products/:id', cors(corsOptions), function (req, res, next) 
  res.json(msg: 'This is CORS-enabled for a whitelisted domain.')
)

【讨论】:

中间件的重点是将给定的操作应用于许多路由。如果需要,您当然可以在中间件级别使用 CORS。或者,您可以将其仅应用于特定路线。您不必将它与app.get() 一起使用。可以和app.use()一起使用就好了。

以上是关于NodeJS - CORS中间件`origin`未定义的主要内容,如果未能解决你的问题,请参考以下文章

节点 JS - CORS 对预检请求的响应未通过访问控制检查:“Access-Control-Allow-Origin”标头的值

NodeJS 或 Nginx 上发生 Access-Control-Allow-Origin cors 错误

为啥没有在 CORS 未命中时设置“Vary: Origin”响应?

Nodejs React CORS 策略:请求的资源上不存在“Access-Control-Allow-Origin”标头

缺少 CORS 标头“Access-Control-Allow-Origin” - CORS 请求未成功

节点 cors 捕获中间件回调错误