基于URL pa的nginx动态proxy_pass

时间:2018-08-29 12:42:30

标签: 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消息中的$ 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参数中混合动态和静态部分

谢谢。

1 个答案:

答案 0 :(得分:2)

您可以使用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;
}

然后是一个处理auth子请求的位置:

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('X-Port: 9999');

现在这将为您的proxy_pass指令端口号设置变量,其余的将由Nginx完成。