node.js - 即使在 Express 和 Express 网关上启用 CORS 后,仍受 CORS 策略的限制
问题描述
我正在使用Express Gateway
代理我的微服务。我从我的react
应用程序中使用Axios
. 但是,呼叫受到限制CORS Policy
。我已经在快速网关和我的身份验证服务中启用了 CORS。我按照官方文档从Express Gateway 的链接和身份验证服务(Express App)的链接启用 CORS。这是我的代码。
快速网关 config.yml
policies:
- log
- proxy
- jwt
- rate-limit
- request-transformer
- cors
pipelines:
authPipeline:
apiEndpoints:
- auth
policies:
-
cors:
-
action:
origin: '*'
methods: 'HEAD,PUT,PATCH,POST,DELETE'
allowedHeaders: ['Content-Type', 'Authorization']
-
log:
action:
message: 'auth ${req.method}'
-
proxy:
action:
serviceEndpoint: di
身份验证服务 app.js
const cors = require('cors');
// Enabling CORS
const corsOptions = {
origin: '*',
methods: ['POST', 'GET', 'PATCH', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization']
}
app.use(cors(corsOptions));
当我尝试使用 Insomnia(像 Postman 这样的客户端)时,我从服务器返回的标头可以在下图中看到。
我在浏览器控制台中收到此错误。
Access to XMLHttpRequest at 'http://127.0.0.1:8080/api/v1/users/login' from
origin 'http://localhost:3000' has been blocked by CORS policy: Response to
preflight request doesnt pass access control check: No 'Access-Control-
Allow-Origin' header is present on the requested resource.
我不确定我错过了什么。如果您需要其他任何东西,请告诉我,我会尽快提供。每一次试图解释我的案例有什么问题的尝试都非常感谢。
编辑:添加 API 调用片段
const config = {
headers: {
'Content-Type': 'application/json',
},
};
const body = JSON.stringify({ email, password });
const res = await axios.post('http://127.0.0.1:8080/api/v1/users/login', body, config);
解决方案
您的“方法”定义不正确。它需要采用 YAML 数组的形式:
methods: [ "HEAD", "PUT", "PATCH", "POST", "DELETE" ]
或者
methods:
- "HEAD"
- "PUT"
- "PATCH"
- "POST"
- "DELETE"
或者
methods:
- HEAD
- PUT
- PATCH
- POST
- DELETE
其他一切看起来都不错,尽管您可能希望将“来源”添加到 allowedHeaders 列表中。
更新 我已经对此做了一些进一步的测试,使用这个迷你快递服务器,然后在 Docker 上运行 API 网关和服务器(在 gateway.config.yml 中进行适当的主机名更改),一切正常,通过来自 localhost 的 curl 进行测试也来自浏览器。
var express = require('express')
var app = express()
// Enabling CORS
const cors = require('cors');
const corsOptions = {
origin: '*',
methods: ['POST', 'GET', 'PATCH', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization']
}
app.use(cors(corsOptions));
function addPath(path) {
app.use(path, function(req, res, next) {
const response = `Hello from ${req.method} ${path}`;
console.log(response);
res.send(response);
});
}
addPath('/api/v1/users/*');
addPath('/api/v1/*');
const port = 5000;
app.listen(port, function () {
console.log(`Example app listening on port ${port}`)
})
我唯一可以建议的另一件事是在 gateway.config.yml 中的 cors 策略条目之前添加另一条日志消息,如下所示:
- 日志:操作:消息:“传入(身份验证):${req.method} ${req.path} 请求 IP:${req.ip} 来源 ${req.headers.origin}”
并检查原产地的价值。如果它不是未定义的,请尝试在代理策略之前添加以下响应转换器(当然,将响应转换器添加到可用策略列表中)。我不得不这样做一两次,但我忘记了必要的情况,所以这是在黑暗中拍摄的。
- response-transformer:
- condition:
name: expression
expression: 'typeof req.headers.origin !== "undefined" && req.headers.origin === "http://localhost"'
action:
headers:
add:
access-control-allow-origin: '"http://localhost"'
推荐阅读
- python - Matplotlib 图形在显示时会聚集在一起
- python - 使用 Python 的 RSA 中的解密时间
- linux - 在 Arch Linux 上哪里可以得到 libGLU.so.1?
- reactjs - 如何在反应组件中使用 Dropzone
- arm - Function App Staging Slot Url 在末尾添加随机数
- python - 如何使用sqlparse解析sql语句
- javascript - 在同一页面上使用两次时 React DONUT 无法正常工作
- python - 如何使用序数分类器?
- c# - 如何在 C# 中将嵌套对象转换为对象
- python - xarray 自动完成触发计算