首次披露:
我是 nginx 新手,很难理解它的配置原则;我读过很多文档(包括“If Is Evil”),但仍然缺乏对许多方面的理解。我打算在不久的将来为生产实现一个 api 网关,但如果可能的话,希望在测试阶段直接在 nginx 配置中实现下面描述的控件
情况:
我在端点的 nginx 反向代理后面运行一个服务https://foobar.org/foo/
。
我希望禁止所有未经身份验证的请求发送到代理服务器除了对于一个特定的端点;我们称之为
/foo/anon_permitted
问题:
我尝试在位置块中的条件中添加一个 AND,如下所示:
`if ($http_authorization = "" && $request != https://foobar.org/foo/anon_permitted) { return 403; }`
但是,nginx 却出现“条件无效”错误。[注:我尝试了上述各种格式排列,但都无济于事]
我尝试了一些其他可用的变量(,,$request_url
)来自$uri
$args
https://nginx.org/en/docs/varindex.html,但结果是一样的。
另外,我知道明确建议不要在位置块中添加条件,所以如果有更好的方法来完成这个配置(除了前面提到的 api 网关),我很想学习它。
问题:
有没有办法实现想要的结果,即返回 403如果条件“a”且不是条件 ‘b’,使用纯 nginx 配置?如果是,该怎么做?
当前(除所需条件外均可工作) nginx 配置如下所示,仅供参考:
server {
server_name foobar.org www.foobar.org;
root /usr/share/nginx/html;
index index.html;
try_files $uri /index.html;
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/foobar.org/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/foobar.org/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location /foo/ {
default_type application/json;
proxy_hide_header Content-Location;
add_header Content-Location /api/$upstream_http_content_location;
proxy_set_header Connection "";
proxy_http_version 1.1;
if ($http_authorization = "") { return 403; }
proxy_pass http://foo_upstream/;
}
}
答案1
您无需使用if
语句检查请求的 URI。只需创建另一个location
块并复制所需的语句即可。
例如:
location /foo/ {
...
if ($http_authorization = "") { return 403; }
proxy_pass http://foo_upstream/;
}
location /foo/anon_permitted {
...
proxy_pass http://foo_upstream/anon_permitted;
}