可以使用“if”来设置 CORS 标头吗?

Posted

技术标签:

【中文标题】可以使用“if”来设置 CORS 标头吗?【英文标题】:Is it okay to use "if" for setting CORS headers? 【发布时间】:2021-04-20 23:40:00 【问题描述】:

处理CORS请求的common solution如下:

location ... 
    add_header  Access-Control-Allow-Origin       ...;
    add_header  Access-Control-Allow-Credentials  ...;
    add_header  Access-Control-Allow-Headers      ...;
    add_header  Access-Control-Allow-Methods      ...;

    if ($request_method = 'OPTIONS') 
        add_header  Access-Control-Allow-Origin       ...;
        add_header  Access-Control-Allow-Credentials  ...;
        add_header  Access-Control-Allow-Headers      ...;
        add_header  Access-Control-Allow-Methods      ...;
        return 204;
    

但是if 是evil。这样使用安全吗?

UPD顺便说一句,从I can see 来看,不需要重复的add_header

【问题讨论】:

没关系。来自引用的nginx.com/resources/wiki/start/topics/depth/ifisevil 页面:“在某些情况下,您根本无法避免使用 if,例如,如果您需要测试一个没有等效指令的变量” 并且有一个 when -it-can't-be-avoided 示例在功能上与问题中的情况相同:if ($request_method = POST ) return 405; 所以答案是:对于这种情况,您无法避免它。就缺乏nginx.com/resources/wiki/start/topics/depth/ifisevil 所描述的风险而言,这并不能使它“安全”——但只是没有真正的替代方案 【参考方案1】:

您不需要if。取几个maps(在locationserver 块之外-> 仅在http 块中有效)。

map $request_method $one

    default '…';
    get '…';
    options '…';
    post '…';


map $request_method $two

    default '…';
    get '…';
    options '…';
    post '…';


map $request_method $three

    default '…';
    get '…';
    options '…';
    post '…';


map $request_method $four

    default '…';
    get '…';
    options '…';
    post '…';

忽略大小写匹配字符串。只要不是普通的正则表达式。

map 的第一个参数是输入(在本例中为$request_method)。根据匹配,在映射的第二个参数中创建一个新变量(在本例中为 $one$two$three$four(您可以根据需要命名))与匹配的 @ 987654333@内容。

more_set_headers 'Access-Control-Allow-Origin: $one';
more_set_headers 'Access-Control-Allow-Credentials: $two';
more_set_headers 'Access-Control-Allow-Headers: $three';
more_set_headers 'Access-Control-Allow-Methods: $four';

未经测试。

【讨论】:

您忘记了return 声明。为什么more_set_headers 糟糕,对。因为我总是使用它——它更智能。但是你确定你需要return 204 吗?例如,如果我使用curl -I 进行查询,则不会发送任何内容。我检查了 Wireshark。 不完全需要,网络礼仪有义务 :) 如果认真,你可能是对的,也可能不是。很难确认。您可以检查这(对OPTIONS 请求的响应200)是否在常见浏览器中没有问题。但你不能 100% 确定它适用于所有人。如果您足够努力地寻找它,您很可能会找到一些用户代理。顺便说一句,我不明白你提出了什么样的要求,以及这证明了什么。 你是对的。 curl -I 仅查询标头 (HEAD)。最好是curl -i -X OPTIONS https://www.google.com/。但是,我只收到 405 Not Allowed。

以上是关于可以使用“if”来设置 CORS 标头吗?的主要内容,如果未能解决你的问题,请参考以下文章

未设置 CORS 标头

使用 Nginx 作为代理来避免 CORS

由于浏览器设置的标头,Safari 拒绝重定向 CORS 请求

在 Tomcat 中设置 CORS 标头

未设置 CORS 标头

CORS XMLHttpRequest 不允许我设置标头