【问题标题】:nginx with sub-request redirection removes query params带有子请求重定向的 nginx 删除查询参数
【发布时间】:2021-05-14 00:07:16
【问题描述】:

我有一个测试应用程序,我通过内部 /auth 子请求对烧瓶后端进行授权。

通过 google 登录进行授权,一旦授权,它就会返回重定向到客户端请求的实际应用程序。

虽然,我在这里遇到了一个问题。如果客户端在原始 URL 中传递了多个查询参数,则之后将被剥离。

例如:

127.0.0.1/test/?query1=val1&query2=val2&query3=val3

变成

127.0.0.1/test/?query1=val1

基本上$request_uri 不包含最初传递的所有查询参数。 URL 编码是这里的罪魁祸首?

下面是我的 Nginx 配置文件。

worker_processes 1;
daemon off;
error_log stderr debug;

events {
    worker_connections 1024;
}

http {
server {
    listen 80;
    server_name  _;

    proxy_set_header Host $host:80;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    location ^~ / {
        proxy_pass http://127.0.0.1:8010/;
    }

    # Internal auth check endpoint.
    location = /auth {
        internal;
        proxy_pass http://127.0.0.1:8010/auth;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Original-URI $request_uri;
    }

    location ^~ /test/ {
        # Internal sub-request auth check before serving the endpoint.
        auth_request /auth;
        proxy_pass http://127.0.0.1:8011/;

        # Redirect to @login if 401 from /auth.
        error_page 401 @login;
    }

    # Catch if 401/unauthorized and redirect for login
    location @login {
        return 302 /authorize?next=$request_uri;
    }
}
}

请帮忙。

【问题讨论】:

  • 只是一种解决方法猜测:尝试set $my_request_uri $request_uri; 之前对其进行编码(再次?)然后使用$my_request_uri?或者改用$my_path$is_args$my_args(您必须使用正则表达式处理$my_path,并使用$args我评论开头的“设置解决方法”处理$my_args)?或者尝试$uri 而不是$request_uri?
  • 嘿感谢您的评论。我以前尝试过,但没有奏效。问题是当 /auth 返回 401 并转到 @login 时,它会忘记查询参数。我可以对查询参数进行编码,例如替换“?”和 '&' 和 '=' 在 nginx 的 url 中?那肯定会解决我的问题。我不知道如何在nginx中做到这一点。请帮忙。
  • @qräbnö ??有更新吗?
  • Nginx 不允许您对内容进行编码 - 您必须使用脚本语言(例如用于 Javascript 的 NJS)

标签: nginx flask nginx-reverse-proxy nginx-config nginx-location


【解决方案1】:

在对 nginx 进行了 2 天的研究后,终于找到了我自己的解决方案。 :D

当我将每个传入请求传递给/auth 时,我在身份验证后端(在我的情况下为 Flask 应用程序)中对 url 进行了编码。 通过像这样更新标头将编码的 url 发送回 nginx。

@app.route('/auth')
def auth():
    if not has_valid_cookies():
        resp = flask.Response("", status=401)
        resp.headers['X-Original-URI'] = url_parse.quote(
            flask.request.headers.get('X-Original-URI', '/')
        )
        return resp
    else:
        return flask.jsonify(success=True)

nginx conf 如下所示,我将带有原始 request_uri 值的 X-Original-URI 发送回后端,在那里对其进行编码并保存编码值,如下所示:

auth_request_set $next_uri $upstream_http_X_Original_URI;

$next_uri 保存编码后的原始请求 url。

    location = /auth {
        internal;
        proxy_pass http://127.0.0.1:8010/auth;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Original-URI $request_uri;
    }

    location ^~ /test/ {
        # Internal sub-request auth check before serving the endpoint.
        auth_request /auth;
        auth_request_set $next_uri $upstream_http_X_Original_URI;
        proxy_pass http://127.0.0.1:8011/;

        # Redirect to @login if 401 from /auth.
        error_page 401 @login;
    }

    # Catch if 401/unauthorized and redirect for login
    location @login {
        return 302 /authorize?next=$next_uri;
    }

【讨论】:

    猜你喜欢
    • 2015-01-20
    • 2014-12-10
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 2018-07-09
    • 1970-01-01
    相关资源
    最近更新 更多