为子目录的每个请求添加标头

为子目录的每个请求添加标头

我有一个 PHP 应用程序的服务器配置,其中通用 X-Frame-Options 标头设置为“SAMEORIGIN”。

部分申请除外应该允许包含在 Iframe 中。方便的是,这些都是从https://example.app/external/*所以我想为对此目录的请求添加不同的 X-Frame-Options 标头(或省略它)。

我现在正为此苦苦挣扎。为了测试,我在server {}配置中的两个地方添加了自定义标头:

server {
  server_name example.app;
  listen 443 ssl;
  root /data/example.app/public;

  add_header X-XSS-Protection "1; mode=block";
  add_header X-Content-Type-Options "nosniff";

  # this one gets added to every request
  add_header X-Test-Header "hello world";

  index index.html index.php;

  charset utf-8;

  location /external/ {
    # this one doesn't show up for https://example.app/external/show/24
    add_header X-Test-Header-2 "Why not";
    try_files $uri $uri/ /index.php?$query_string;
  }

  location / {
    try_files $uri $uri/ /index.php?$query_string;
  } 


  location ~ \.php$ {
    fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    include fastcgi_params;
  }

  location ~ /\.(?!well-known).* {
    deny all;
  }  

  # ssl config
  # ...
  # gip config
  # ...

}

如您所见,我在配置文件中添加了两个测试标头。第一个出现了;但专门针对子目录的那个没有随响应一起发送。我认为这与位置块的匹配有关,所以我尝试了这些

location /external/ {}
location = /external/ {}
location ~* /external/ {}
location ^~ /external/ {}

但是所有请求(例如 example.app/external/nl/something/45)只有X-Test-Header和 没有X-Test-Header-2

知道为什么吗?

答案1

如果不阻止所有其他指令生效,则无法将此指令添加到。请add_header参阅locationadd_header文档, 特别:

当且仅当当前级别上没有定义 add_header 指令时,这些指令才会从上一级别继承。

另外,location您添加的块是不是URI 最终被处理的位置。该try_files指令将在内部重写 URI,从而/index.php使 Nginx 使用location ~ \.php$块来处理请求。

您可以使用add_header带有变量的语句,并使用 设置该变量map。将该语句与其他语句放在同一个块中add_header。请参阅这个文件了解详情。

例如:

map $request_uri $myheader {
    default           "Default Value";
    ~^/external/      "External Value";
}

server {
    ...
    add_header X-XSS-Protection       "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
    add_header X-Test-Header          $myheader;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    location ~ \.php$ { 
        ... 
    }
}

另外,如果将变量的值设置为"",则会默默地丢弃标题。

相关内容