我们正在尝试使用 ngx_postgres 模块通过 NGINX 进行基本身份验证。我们希望从查询结果对中检索一个值并将其添加到 HTTP 标头,然后将其代理到另一台服务器。
我们已经成功通过 postgres 进行身份验证,但问题在于将结果对传递到代理上。我们目前使用的代码如下:
location = /test_auth {
internal;
postgres_escape $user $remote_user;
postgres_escape $pass $remote_passwd;
postgres_pass geo_database;
postgres_query "select user_name,contract_id,access_token from schema_name.table_name where user_name=$user and password=md5($pass);";
postgres_rewrite no_rows 401;
more_set_headers -s 401 'WWW-Authenticate: Basic realm="Restricted"';
postgres_output none;
postgres_set $query_val 0 0 required;
}
location /test/ {
auth_request /test_auth;
proxy_pass http://back_end_server/public-dev/;
proxy_set_header test $query_val;
proxy_redirect http://back_end_server/public-dev/ http://example_domain.com/;
}
这是我们尝试过的许多不同方法的子集。本例中的问题是 query_val 似乎在子请求中被破坏。当 postgres 调用不在子请求中时,我们能够成功检索查询结果对,但这会禁用我们的身份验证。
我们还尝试在主位置进行简单查询,然后将这些数据代理到其他位置,但失败了。如果我们将查询结果对定向到本地资源(如 index.html 文件),它将被正确添加到标头文件中,但一旦我们尝试将其添加到 http 标头并将其发送到代理,它就不再存在。
任何有关此事的建议都将不胜感激。
[更新]我花了一整天时间阅读有关我正在使用的模块的信息,我真的认为这是模块阶段顺序的问题。我感觉代理重写是在 postgres 身份验证子请求实际返回结果之前发生的。我将继续调查。任何帮助仍然值得感激。
答案1
这个问题的解决方案最终是使用 auth_request_set 函数在适当的 NGINX 阶段提取正确的值。以下代码是可行的解决方案。
location = /test_auth {
internal;
postgres_escape $user $remote_user;
postgres_escape $pass $remote_passwd;
postgres_pass geo_database;
postgres_query "select user_name,contract_id,access_token from schema_name.table_name where user_name=$user and password=md5($pass);";
postgres_rewrite no_rows 401;
more_set_headers -s 401 'WWW-Authenticate: Basic realm="Restricted"';
postgres_output none;
postgres_set $query_val 0 0 required;
}
location /test/ {
auth_request /test_auth;
auth_request_set $proper_query_val $query_val;
proxy_pass http://back_end_server/public-dev/;
proxy_set_header test $proper_query_val;
proxy_redirect http://back_end_server/public-dev/ http://example_domain.com/;
}