【问题标题】:Allow multiple CORS domain in express js在 express js 中允许多个 CORS 域
【发布时间】:2015-01-15 06:32:50
【问题描述】:

如何以简化的方式允许 CORS 使用多个域。

我有

 cors: {
        origin: "www.one.com";
    }

    app.all('*', function(req, res, next) {
            res.header("Access-Control-Allow-Origin", cors.origin);
            res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
            next();
        });

这在origin 中只提到一个域时有效

但是,如果我想将 origin 作为域数组,并且我想允许原始数组中的所有域使用 CORS,我就会有这样的东西 -

cors: {
            origin: ["www.one.com","www.two.com","www.three.com"];
        }

但问题是下面的代码不起作用 -

app.all('*', function(req, res, next) {
                res.header("Access-Control-Allow-Origin", cors.origin);
                res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
                next();
            });

如何让res.header 通过cors.origin 获取一系列域?

【问题讨论】:

  • 用“*”代替一两个域有什么问题?
  • * 不会放置任何 CORS 过滤器。 * 基本上会允许我显然不想要的所有域。
  • 记住 cors 只影响浏览器,所以安全性与 cors 无关。
  • 同意,但是放 * 是个好习惯吗?
  • @dandavis 您的 cmets 是 5 年前制作的,因此您的观点可能已经改变,但对于未来的读者来说,CORS 是关于安全性的。如果您使用 cookie,这是防止跨站点请求伪造的第一道防线(这就是浏览器默认阻止跨源请求的原因)。 “*”策略意味着任何站点都可以作为您的用户提出请求(假设没有其他 CSRF 缓解措施)。如果该用户是您服务的管理员,恶意网站可能会造成很大破坏。

标签: javascript node.js express cors


【解决方案1】:

我会推荐 cors 模块:https://www.npmjs.org/package/cors 它会为你做这种事情 - 检查“Configuring CORS w/ Dynamic Origin”-Section

【讨论】:

  • 有必要使用模块吗?我正在寻找原生解决方案。
  • @Ajey - 模块只是其他人已经编写的用于解决您的问题的代码。在 nodejs 编程中,庞大的开源模块库是最大的优势之一——忽略它们将是一种耻辱。如果你愿意,你可以浏览 github 上的 CORS 模块来查看代码,看看它做了什么。代码是here
  • @Johannes - 我使用了 npm 模块。谢谢。
  • 该模块现在是 express 的一部分,您可以在expressjs.com/en/resources/middleware/…查看此答案中提到的文档
  • ...此外,您现在可以将多个 URL 作为 CORS 来源添加为数组 - 请参阅 configuration options
【解决方案2】:

让我们了解此标头的工作原理。 “Access-Control-Allow-Origin”只接受一个字符串。 因此,要使其动态化,您需要从 http 标头中获取请求主机。对照您的授权域数组进行检查。如果存在,则将其作为值添加到标头中,否则添加默认值将禁止未经授权的域访问 API。

对此没有本机实现。您可以使用下面的代码自己完成。

cors: {
            origin: ["www.one.com","www.two.com","www.three.com"],
            default: "www.one.com"
        }

app.all('*', function(req, res, next) {
                var origin = cors.origin.indexOf(req.header('origin').toLowerCase()) > -1 ? req.headers.origin : cors.default;
                res.header("Access-Control-Allow-Origin", origin);
                res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
                next();
            });

【讨论】:

  • 如果您访问 jquery.com 并在开发人员工具控制台中将 $.ajax 设置为 www.one.com,那么您在 req.header('host') 上获得了什么价值?,在我的测试中,我得到 www.one.com 至极会让检查认为这是一个允许的域,任何人都可以确认这一点或澄清我的测试中有什么问题吗?
  • req.header('host') 更改为req.header('origin')
【解决方案3】:

使用 Node、cors 中间件,请确保将 / 从 url 中移除,否则如果浏览器中的 url 没有它显示,ELSE cors 可能会失败。即

var corsOptions = {
origin: ["http://www.example.com/","http://localhost:3000"],
optionsSuccessStatus: 200 // For legacy browser support
}

app.use(cors(corsOptions));

失败并且会给我 cors 错误,因为浏览器会将 URL 显示/读取为 http://www.example.com,下面的工作并且更具包容性,并且应该适用于 http://www.example.com 以及除此之外的任何内容,即 http://www.example.com/ 或 @ 987654324@等

var corsOptions = {
origin: ["http://www.example.com","http://localhost:3000"],
optionsSuccessStatus: 200 // For legacy browser support
}

app.use(cors(corsOptions)); 

【讨论】:

    【解决方案4】:

    事实上,Access-Control-Allow-Origin 标头的值应该与 Origin 标头的值相同,只要您愿意。

    所以基于你的代码就行了

    cors: {
        origin: ["www.one.com","www.two.com","www.three.com"]
    }
    
    
    
    app.all('*', function(req, res, next) {
                let origin = req.headers.origin;
                if(cors.origin.indexOf(origin) >= 0){
                    res.header("Access-Control-Allow-Origin", origin);
                }         
                res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
                next();
            });
    

    【讨论】:

    • @nameless 不错的想法,但不允许使用该域:["www.one.com","www.two.com","www.three.com"].indexOf("https://www.one.com.my.malicious.site.com") === -1
    【解决方案5】:

    嗨,我想分享我的解决方案:!!! 如果您使用远程服务器并在 localhost(webpack 或其他开发环境)上开发,这些代码可以工作!干杯!!

    let ALLOWED_ORIGINS = ["http://serverabc.com", "http://localhost:8080"];
    app.use((req, res, next) => {
        let origin = req.headers.origin;
        let theOrigin = (ALLOWED_ORIGINS.indexOf(origin) >= 0) ? origin : ALLOWED_ORIGINS[0];
        res.header("Access-Control-Allow-Origin", theOrigin);
        res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    
        next();
    })
    

    【讨论】:

      猜你喜欢
      • 2020-07-02
      • 1970-01-01
      • 2018-02-22
      • 1970-01-01
      • 2022-01-14
      • 2018-08-17
      • 2017-11-23
      • 2016-08-03
      相关资源
      最近更新 更多