如何解决带有 HTTPS 重定向的 Nginx 入口控制器尾随斜杠
我正在尝试使用带有 Nginx 入口控制器的入口将请求从 HTTP 重定向到 HTTPS。我的应用程序是用 Django v3.0.7 编写的,我的 Nginx 控制器是 v0.46.0 和 k8s v1.19.8。
我有以下入口:
apiVersion: networking.k8s.io/v1
kind: Ingress
Metadata:
name: INGRESS-NAME
namespace: INGRESS-NS
annotations:
kubernetes.io/ingress.class: "Nginx"
Nginx.ingress.kubernetes.io/use-regex: "true"
Nginx.ingress.kubernetes.io/ssl-redirect: "true"
Nginx.ingress.kubernetes.io/rewrite-target: /api/v1/$1/
cert-manager.io/cluster-issuer: "ISSUER-NAME"
Nginx.ingress.kubernetes.io/permanent-redirect-code: '308'
spec:
tls:
...
rules:
- host: MY-DOMAIN
http:
paths:
- path: /api/v1/?(.*)
pathType: Prefix
backend:
service:
name: SVC-NAME
port:
number: SVC-PORT
在 https://.../api/v1/get-token/
的请求,引发此错误:
[05/May/2021:20:39:49 +0000] "POST /api/v1/get-token// HTTP/1.1" 404
=> POST 在最后得到一个额外的 /
。但是使用 HTTP 或 https://.../api/v1/get-token
(没有尾随 /
)的相同请求是可以的。
如果我删除
annotations:
Nginx.ingress.kubernetes.io/rewrite-target: /api/v1/$1/
重定向删除尾随 /
并导致所有 HTTP POST 请求中的 POST 变为 GET,从而导致 403 - 方法不允许,如 Nginx 日志中所示:
[05/May/2021:20:54:52 +0000] "POST /api/v1/get-token HTTP/1.1" 308 164
[05/May/2021:20:54:53 +0000] "POST /api/v1/get-token HTTP/1.1" 301 0
[05/May/2021:20:54:53 +0000] "GET /api/v1/get-token/ HTTP/1.1" 405
但 HTTP POST 请求与 http://.../api/v1/get-token//
(两个尾随 /
)一起工作正常。
有没有办法解决这个问题? 308 HTTP -> HTTPS 重定向很重要,所以我无法删除它,但是有没有办法强制请求只有一个尾随 /
?谢谢。
解决方法
这里有两个问题
问题 #1
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /api/v1/$1/
导致发送到 https://.../api/v1/get-token/
的请求以 HTTP 404 Not Found 结束,但 https://.../api/v1/get-token
工作正常。
为什么?
因为 /
rewrite 末尾的尾随 nginx.ingress.kubernetes.io/rewrite-target: /api/v1/$1/
被添加到 URL 中,而 /api/v1/get-token//
导致资源不存在。
怎么办?
将 path
键更改为 /api/v1/?(.*\b)/
。我不是 100% 确定它会起作用,但值得一试。
或
从重写中删除尾随 /
。
现在,这样做会导致问题 #2。
问题 #2
对 https://.../api/v1/get-token
的请求以 405 Method Not Allowed 结束。
为什么?
第一次重定向工作正常 (HTTP 308),但是请求再次使用 HTTP 301 重定向。
关于 HTTP 301 的 MDN 文章指出:
即使规范要求在执行重定向时不更改方法(和主体),但并非所有用户代理都与它保持一致 - 您仍然可以在那里找到这种类型的有漏洞的软件。因此,建议仅使用 301 代码作为对 GET 或 HEAD 方法的响应,而对 POST 方法使用 308 永久重定向,因为在此状态下明确禁止方法更改。
基本上HTTP 301会导致POST
变成GET
,而GET
是不允许的,因此HTTP 405。 >
怎么办?
确保不要重定向请求两次,尤其是使用 HTTP 301。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。