首页 > 解决方案 > nginx auth_request 指令和带有 set 的位置块的问题

问题描述

我在服务器部分定义了一个名为 $host_header 的变量,该变量在位置级别被覆盖。它工作得非常好,因为所有集合都是在重写阶段完成的,所以在任何 proxy_pass 指令之前。最终,“test-nginx”的 proxy_pass 与 Host 标头“位置级别”一起使用。但是,当我将 auth_request 指令(在我的示例中始终返回 200 并且它在访问阶段运行,因此在所有设置之后)添加到位置块时(这就是魔法),proxy_pass 与主机标头“服务器-level”,在我看来这是一个错误。它在 nginx 1.19.1 上

这是示例代码。任何想法为什么会发生?这是一个错误还是我做错了什么?

server {
listen 80;

server_name "local.main.server";
set $host_header "server level";

proxy_set_header Host $host_header;

location /test {
    auth_request /auth;

    set $host_header "location level";

    # call backend server
    proxy_pass http://test-nginx;
}

location = /auth {
    internal;

    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URI $request_uri;

    # this simply return 200
    proxy_pass http://test-nginx;
}

}

标签: nginxauth-request

解决方案


对于这个奇怪的问题,我找到了一个非常好的解决方法。通过使用 NJS 模块中的“js_set”指令,我们可以创建另一个变量 $target_host_header 并将 getTargetHeader 函数的结果分配给它:

...
load_module /usr/lib/nginx/modules/ngx_http_js_module.so;
...
http {
  ...
  js_import NJS from /path/to/file/with/functions.js;
  ...
  js_set $target_header NJS.getTargetHeader;
  proxy_set_header Host $target_header;
  ...
}

仍然在服务器部分我们可以设置 $host_header 变量,但在一个位置我们必须设置不同的变量 $proxy_host_header:

server {
   ...
   set $host_header "server level";
   
   location /test {
      set $proxy_host_header "location level";
      proxy_pass http://SOMEENDPOINT;
   }
   ...
}

这里是 njs 函数:

function getTargetHostHeader(r) {
    if (r.variables.hasOwnProperty('proxy_host_header') && r.variables.proxy_host_header.length > 0) {
       return r.variables.proxy_host_header;
    } else {
       return r.variables.host_header;
    }
}

推荐阅读