kubernetes-ingress - 带有 HTTPS 重定向的 Nginx 入口控制器尾部斜杠
问题描述
带有 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 最后得到一个额外/
的。https://.../api/v1/get-token
但是使用 HTTP 或(没有尾随)的相同请求/
很好。
如果我删除
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /api/v1/$1/
重定向会删除尾随/
,并导致 POST 在所有 HTTP POST 请求中变成 GET,从而导致 403 - Method not allowed 如 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//
导致不存在的资源。
该怎么办?将密钥
更改为。我不是 100% 确定它会起作用,但值得一试。或从重写中
删除尾随。
现在,这样做会导致问题 #2。path
/api/v1/?(.*\b)/
/
问题 #2
请求以405 Method Not Allowedhttps://.../api/v1/get-token
结尾。
为什么?
第一次重定向工作正常(HTTP 308),但是请求再次使用HTTP 301重定向。
MDN 关于 HTTP 301 的文章指出:
即使规范要求在执行重定向时不要更改方法(和主体),但并非所有用户代理都与它保持一致 - 您仍然可以在那里找到这种类型的错误软件。因此,建议仅将 301 代码用作 GET 或 HEAD 方法的响应,而将 308 永久重定向用于 POST 方法,因为在此状态下明确禁止更改方法。
基本上HTTP 301会导致POST
成为GET
,并且GET
是不允许的,因此是HTTP 405。
该怎么办?
确保不要将请求重定向两次,尤其是使用HTTP 301时。
推荐阅读
- python - 在redis中扫描键时是否有推荐的计数大小?
- vb.net - 无法在 Visual Basic 中对从系统获取的文件进行排序
- fortran - 正确设置随机种子以实现可重复性
- wordpress - 未捕获的类型错误:无法读取 null wp-embed.min.js 的属性“秘密”
- postgresql - Postgresql 表的大小 - 在表行或列上增加?
- c# - 在单个类文件中添加多个单元测试 - Selenium
- php - Woocommerce 产品自定义字段:检查输入是否已存在
- angular - Angular/rxjs6 - 在 PUT 之前获取
- javascript - 当至少一个复选框被选中时如何将值发布到数据库中
- javafx - JavaFX XYChart 在替换所有系列时的奇怪行为