Конечный слэш Nginx Ingress Controller с перенаправлением HTTPS

Конечный слэш Nginx Ingress Controller с перенаправлением HTTPS

Я пытаюсь перенаправить запросы с HTTP на HTTPS, используя Ingress с Nginx Ingress Controller. Мое приложение написано на 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/

Перенаправление удаляет трейлинг и заставляет POST превращаться в GET во всех запросах HTTP POST, вызывая 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 ответ

Здесь есть две проблемы

Проблема #1

      annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /api/v1/$1/

вызывает запросы, отправленные на https://.../api/v1/get-token/чтобы закончить HTTP 404 Not Found, но работает нормально.

Почему?
Поскольку трейлинг в конце 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 Метод запрещен .

Почему?
Первое перенаправление работает нормально (HTTP 308), однако запрос снова перенаправляется с помощью HTTP 301.

В статье MDN о HTTP 301 говорится:

Даже если спецификация требует, чтобы метод (и тело) не изменялся при выполнении перенаправления, не все пользовательские агенты согласуются с ним - вы все равно можете найти этот тип программного обеспечения с ошибками. Поэтому рекомендуется использовать код 301 только в качестве ответа для методов GET или HEAD и вместо этого использовать постоянное перенаправление 308 для методов POST, поскольку изменение метода явно запрещено с этим статусом.

В основном HTTP 301 вызывает POST стать, и GETне разрешено, следовательно, HTTP 405.

Что с этим делать?
Не перенаправляйте запросы дважды, особенно с HTTP 301.

Другие вопросы по тегам