nginx 反向代理与查询参数修改

nginx 反向代理与查询参数修改

我有一个应用程序在 nginx 后面不支持 SSL,因此我需要执行以下操作

http://example.com/f1/f2/page?next_page=http%3A//example.com/f3/new_page

必须改为

https://example.com/f1/f2/page?next_page=https%3A//example.com/f3/new_page

所以有两件事要做,改变方案,我可以做到,并且改变 url 参数,我在这方面取得了一些成功,但它并不完全起作用。

我找到了一个可以完成我想要做的事情的页面,但是它对我来说不起作用:https://blog.imaginea.com/modifying-query-parameters-nginx-in-reverse-proxy-mode/

我的 nginx 配置的相关部分:

server {
    listen 443 ssl;
    server_name example.com;

    ssl on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_certificate /path/to/bundle.crt;
    ssl_certificate_key /path/to/bundle.key;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    underscores_in_headers on;
    rewrite_log on;

    location / {

        if ($args ~* (.*)(next_page=http%3A)(.*)) {
            set $args $1next_page=https%3A$3;
            rewrite ^(.*)$ $1;
        }

        proxy_pass http://127.0.0.1:80;
        proxy_redirect http:// https://;

        proxy_set_header Host $host;
        proxy_set_header HTTPS "on";
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-Host $host:$server_port;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-Port 443;
    }
}

nginx_错误日志:

2017/09/20 13:48:13 [notice] 25115#0: *1 "(.*)(next_page=http%3A)(.*)" matches "next_page=http%3A//example.com/f3/new_page", client: X.X.X.X, server: example.com, request: "GET /f1/f2/page?next_page=http%3A//example.com/f3/new_page HTTP/1.1", host: "example.com"
2017/09/20 13:48:13 [notice] 25115#0: *1 "^(.*)$" matches "/f1/f2/page", client: X.X.X.X, server: example.com, request: "GET /f1/f2/page?next_page=http%3A//example.com/f3/new_page HTTP/1.1", host: "example.com"
2017/09/20 13:48:13 [notice] 25115#0: *1 rewritten data: "/f1/f2/page", args: "next_page=https3A//example.com/f3/new_page", client: X.X.X.X, server: example.com, request: "GET /f1/f2/page?next_page=http%3A//example.com/f3/new_page HTTP/1.1", host: "example.com"
2017/09/20 13:48:13 [notice] 25115#0: *1 "(.*)(next_page=http%3A)(.*)" does not match "next_page=https3A//example.com/f3/new_page", client: X.X.X.X, server: example.com, request: "GET /f1/f2/page?next_page=http%3A//example.com/f3/new_page HTTP/1.1", host: "example.com"
2017/09/20 13:48:13 [notice] 25115#0: *1 "(.*)(next_page=http%3A)(.*)" does not match "", client: X.X.X.X, server: example.com, request: "GET /f1/f2/cookie/++resource++baseimg/regio.ico HTTP/1.1", host: "example.com", referrer: "https://example.com/f1/f2/page?next_page=http%3A//example.com/f3/new_page"

因此,proxy_redirect 会更改方案(我需要这样做,因为应用程序本身有时会重定向到某个 http-URI),proxy_pass 会将其转发到正确的服务器,并且参数会更改,但请求不会更改。我在这里遗漏了什么?

浏览器中显示的URL:

https://example.com/f1/f1/page?next_page=http%3A//example.com/f3/new_page

顺便说一句。nginx 版本是 1.10.1,目前我无法升级它

答案1

因此,最终奏效的是改变

if ($args ~* (.*)(next_page=http%3A)(.*)) {
    set $args $1next_page=https%3A$3;
    rewrite ^(.*)$ $1;
}

proxy_pass http://127.0.0.1:80;
proxy_redirect http:// https://;

if ($args ~* (.*)(next_page=http%3A)(.*)) {
    set $args $1next_page=https%3A$3;
    rewrite ^.*$ $1 redirect;
}

proxy_pass http://127.0.0.1:80$uri$is_args$args;
proxy_redirect http:// https://;

答案2

一个可能的问题是 nginx 可能不允许设置它自己定义的变量。我不确定,这只是一个有根据的猜测。

这意味着您应该对参数使用不同的名称。

更好的是使用该map功能来获取新的查询参数。

http配置层面,添加如下图:

map $args $newargs {
    default $args;
    ~^(.*)next_page=http:(.*)$ $1next_page=https:$2;
}

在您的server块中,使用以下内容location

location / {
    proxy_pass http://127.0.0.1:80$uri$is_args$newargs;
    ...
}

无论如何,您的设置看起来有点奇怪,因为您正在代理到 http 端口,我假设它在服务器上的 nginx 上运行......我只需对https所有到该http端口的请求进行重定向。

相关内容