简体   繁体   English

在入口 nginx 中启用 tls 时没有“Access-Control-Allow-Origin”

[英]No 'Access-Control-Allow-Origin' when tls enabled in ingress nginx

I know that it seems that my question has a lot of answers already but bear with me.我知道我的问题似乎已经有了很多答案,但请耐心等待。

I have a Django application running on k8s cluster with nginx ingress setup with letsencrypt staging tls certificate (the problem occurs with production certificate also).我有一个 Django 应用程序在 k8s 集群上运行,nginx 入口设置和letsencrypt staging tls证书(问题也出现在生产证书上)。

I don't know if it matters but application uses Basic Authentication to authorize users which is setup with drf build-in authentication system.我不知道这是否重要,但应用程序使用Basic Authentication来授权使用drf内置身份验证系统设置的用户。

I've setup CORS as follows:我已经设置 CORS 如下:

### ingress.yaml

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: app-routing
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-staging"
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, PATCH, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,X-CSRFToken"
spec:
  tls:
  - hosts:
      - api.example.com
    secretName: app-ingress-tls
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: service-backend
              servicePort: 80

and in Django application:在 Django 应用程序中:

### settings.py
...
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

CORS_ORIGIN_ALLOW_ALL = True
# I also tried setting:
# CORS_ORIGIN_WHITELIST = [
#     "https://example.com",
#     "https://www.example.com"
# ]
#

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.BasicAuthentication'
    ],
}

...

But still when I send request from my frontend app I'm getting error但是当我从我的前端应用程序发送请求时,我仍然收到错误

Access to XMLHttpRequest at 'https://api.example.com/somepath' from origin 'https://example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

The weird thing is that when I disable tls in ingress the issue is gone.奇怪的是,当我在入口中禁用 tls 时,问题就消失了。 Tho with tls enabled, if I send request using postman or curl like that:启用 tls 后,如果我使用 postman 或curl发送请求,如下所示:

curl -i -k -H "Authorization: Basic token" https://api.example.com/somepath

I'm getting response with headers as expected:我得到了预期的标题响应:

HTTP/2 200
server: nginx/1.17.7
date: Mon, 06 Jul 2020 18:58:50 GMT
content-type: application/json
content-length: 9
vary: Accept, Origin
allow: GET, HEAD, OPTIONS
x-frame-options: DENY
x-content-type-options: nosniff
strict-transport-security: max-age=15724800; includeSubDomains
access-control-allow-origin: https://example.com
access-control-allow-credentials: true
access-control-allow-methods: PUT, GET, POST, PATCH, OPTIONS
access-control-allow-headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,X-CSRFToken

I presume that headers are there because ingress itself added them (?)我认为标头在那里是因为入口本身添加了它们(?)

I'm pretty new to whole devops world so I would appreciate any tip on where to look or what to check.我对整个 devops 世界都很陌生,所以我会很感激任何关于在哪里查看或检查什么的提示。 Most of answers to this questions suggests to properly set CORS_ORIGIN_ALLOW_ALL and/or CORS_ORIGIN_WHITELIST which I already tried.这个问题的大多数答案都建议正确设置我已经尝试过的CORS_ORIGIN_ALLOW_ALL和/或CORS_ORIGIN_WHITELIST

The issue you ran into is not related to configuration.您遇到的问题与配置无关。 Bottom line is that you try to send requests across different subdomains (which CORS is preventing).底线是您尝试跨不同的子域发送请求(CORS 正在阻止)。 You need either set nginx.ingress.kubernetes.io/cors-allow-origin to "https://api.example.com" or serve API from the same domain - eg.您需要将nginx.ingress.kubernetes.io/cors-allow-origin设置为"https://api.example.com"或从同一域提供 API - eg. https://example.com/api . https://example.com/api

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM