问题描述
我使用 Express Gateway
代理我的微服务。我正在使用 react
从我的 Axios
应用程序访问网关。但是,调用会受到 CORS Policy
的限制。我已经在快速网关和我的身份验证服务中启用了 CORS。我按照官方文档从这个 link 为 Express Gateway 和这个 link 为身份验证服务(Express App)启用 CORS。这是我的代码。
Express Gateway 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.
我不确定我错过了什么。如果您需要其他任何东西,请告诉我,我会尽快提供。每一次试图解释我的案子出了什么问题的尝试都非常感谢。
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
其他一切看起来都不错,尽管您可能希望将“origin”添加到 allowedHeaders 列表中。
更新 我已经对此做了一些进一步的测试,使用这个迷你快递服务器,然后在 Docker 上运行 API 网关和服务器(在 gateway.config.yml 中进行适当的主机名更改),一切都按我的预期工作,通过来自 localhost 和也来自浏览器。
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} origin ${req.headers.origin}”
并检查 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"'