基于url pa的nginx动态proxy_pass

标签 nginx nginx-reverse-proxy

我目前在我的 nginx 配置文件中有以下代理传递定义:

location /pass/ {
    proxy_pass http://localhost:9999/pass/;
    proxy_redirect     off;
    proxy_set_header   Host $host;
}

这按预期工作 -/pass 请求被转发到在端口 9999 上运行的应用程序。

现在,我要做的是使端口转发部分动态化,如下所示:

location /pass/<input> {
    {a $port variable here that is evaluated via a script (php?)}
    proxy_pass http://localhost:$port/pass/;
    proxy_redirect     off;
    proxy_set_header   Host $host;
}

对/pass/ABCD1234 的请求应转发到端口 9898,对/pass/ABCD5678 的请求应转发到端口 9797。

请注意,流程是动态的 - 因此,从 ABCD1234 到 9898 的映射应该通过某种脚本(可能是 PHP?)发生,并且基于脚本的输出(一个端口),proxy_pass 应该将请求转发给那个端口。

请在这方面提供帮助。

更新:

我不想从 URI 输入中获取 proxy_pass 端口,而是希望通过 cookie 来获取它。所以,这是更新后的代码块:

location /pass/ {
    add_header X-debug-message $host always;
    add_header X-debug-message $cookie_sdmport;
    set $proxyurl http://127.0.0.1:$cookie_theport/pass/;
    add_header X-debug-message $proxyurl;
    proxy_pass $proxyurl;
    proxy_redirect     off;
    proxy_set_header   Host $host;
}

使用此代码,循环 301 重定向回浏览器。当我切换回静态端口时,它又可以工作了!奇怪的! X-debug-message 中的 $proxyurl 在浏览器上看起来是正确的。所以,想知道为什么 proxy_pass 正在执行 301!

更新 2:

最终使用以下设置进行转发:

    set $targetIP 127.0.0.1;
    set $targetPort $cookie_passport;
    proxy_pass http://$targetIP:$targetPort$request_uri;

不确定为什么上面发布的解决方案一直在 301 旋转 - 我猜 nginx 不喜欢在 proxy_pass 参数中混合动态和静态部分

谢谢。

最佳答案

您可以使用 auth_request 模块来完成此操作。虽然它不是默认构建的,但您可以通过运行以下命令来确定您是否拥有它:

nginx -V 2>&1 | grep -qF -- --with-http_auth_request_module && echo ":)" || echo ":("

如果您看到笑脸,那么您就可以开始了。

location ~* /pass/(.*) { <- regex capture for your variable
    auth_request /auth;  <- location to process request
    auth_request_set $proxyurl http://localhost:$upstream_http_x_port/pass/; <- set $proxyurl using value returned in x-port header of your php script
    add_header x-my-variable $1; <- Pass variable from regex capture to auth location
    proxy_pass $proxyurl;
}

然后是处理授权子请求的位置:

location /auth {
    internal; <- make location only accessible to internal requests from Nginx
    proxy_set_header x-my-variable $http_x_my_variable; <- pass variable to php
    proxy_pass_request_body off; <- No point sending body to php
    proxy_set_header Content-Length "";
    proxy_pass http://your-php-script/file.php;
}

这个模块实际上是为了访问控制,所以如果你的 php 脚本返回响应代码 200 那么客户端将被允许访问,如果它返回 401 或 403 那么访问将被拒绝。如果您不关心这个,那么只需将它设置为始终返回 200。

做任何你需要的评估,让你的 php 返回前面定义的 header 中的端口:

header('X-Port: 9999');

现在这会为您的 proxy_pass 指令端口号设置变量,Nginx 会完成剩下的工作。

关于基于url pa的nginx动态proxy_pass,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52077768/

相关文章:

docker - 如何为多个环境创建单个 NGINX.conf 文件

node.js - 带路径重写的 Nginx 代理配置

ssl - oauth2_proxy 不要求身份验证

node.js - JSON 不得超过 1000000 字节

ruby-on-rails - 隐藏乘客/Nginx 服务器中的 header

Nginx 有条件地重写 uri

python - 如何使用 jwilder/nginx-proxy 部署 flask 或 django 应用程序?

nginx - CORS 请求中未接受响应状态 201

redirect - NGINX https ://www. example.com/index.php 到 https ://www. example.com/redirect 怎么办?

非默认端口上的反向代理背后的 Spring Boot Cors