ssl - 在入口 nginx 中启用 tls 时没有“Access-Control-Allow-Origin”
问题描述
我知道我的问题似乎已经有了很多答案,但请耐心等待。
我有一个在 k8s 集群上运行的 Django 应用程序,带有 nginx 入口设置和letsencrypt staging tls证书(问题也出现在生产证书上)。
我不知道这是否重要,但应用程序用于Basic Authentication
授权使用drf
内置身份验证系统设置的用户。
我已按如下方式设置 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
在 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'
],
}
...
但是当我从我的前端应用程序发送请求时,我仍然收到错误
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.
奇怪的是,当我在入口中禁用 tls 时,问题就消失了。curl
如果我使用邮递员或类似方式发送请求,则启用了 tls :
curl -i -k -H "Authorization: Basic token" https://api.example.com/somepath
我得到了预期的标题响应:
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
我认为标头在那里是因为入口本身添加了它们(?)
我对整个 devops 世界都很陌生,所以我会很感激任何关于在哪里查看或检查什么的提示。这个问题的大多数答案都建议正确设置CORS_ORIGIN_ALLOW_ALL
和/或CORS_ORIGIN_WHITELIST
我已经尝试过。
解决方案
您遇到的问题与配置无关。底线是您尝试跨不同的子域发送请求(CORS 正在阻止)。您需要设置
nginx.ingress.kubernetes.io/cors-allow-origin
或"https://api.example.com"
提供来自同一域的 API - 例如。https://example.com/api
.
推荐阅读
- javascript - 如何将 Javascript 中的日志字符串解析为 JSON
- powershell - 在powershell中使用Invoke-Sqlcmd时区分sql错误和空结果
- ios - StackView 布局并排并在彼此之上(如 zStack)
- arrays - 从C中的矩阵中删除元素
- javascript - 有条件地为小屏幕添加滚动视图
- c++ - 为什么 PortAudio 录制的声音里面有空格?
- spring - 带有 Kafka 消费者的 Spring Boot 作业调度程序
- ionic-framework - 使用应用程序更新的电容器应用程序版本检查和更新程序对话框
- flutter - 在 null 上调用了 getter 项
- oracle - 可编辑视图和可编辑视图之间的区别?