即使在 Express 和 Express 网关上启用 CORS 后仍受 CORS 策略限制
Restricted by CORS policy even after enabling CORS on Express and Express gateway
我正在使用 Express Gateway
来代理我的微服务。我正在使用 Axios
从我的 react
应用访问网关。但是,调用受到 CORS Policy
的限制。我在快速网关和我的身份验证服务中启用了 CORS。我按照官方文档从这个 link for Express Gateway and this link 启用 CORS 以进行身份验证服务(Express App)。这是我的代码。
快速网关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 这样的客户端)时,我从服务器返回的 Headers 可以在下图中看到。
我在浏览器控制台中收到此错误。
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
其他一切看起来都不错,尽管您可能想将“origin”添加到 allowedHeaders 列表中。
更新
我对此做了一些进一步的测试,使用这个迷你快速服务器,然后 运行 API 网关和 Docker 上的服务器(在 gateway.config.yml 中适当更改主机名),以及通过本地主机和浏览器的 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 策略条目 之前添加另一条日志消息,如下所示:
-
日志:
行动:
消息:“传入(auth):${req.method} ${req.path} 请求 IP:${req.ip} 来源 ${req.headers.origin}”
并检查原始值。如果不是 undefined,尝试在代理策略之前添加以下 response-transformer(当然,将 response-transformer 添加到可用策略列表中)。我不得不这样做一两次,但我忘记了必要的情况,所以这是在黑暗中拍摄的。
- 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"'
我正在使用 Express Gateway
来代理我的微服务。我正在使用 Axios
从我的 react
应用访问网关。但是,调用受到 CORS Policy
的限制。我在快速网关和我的身份验证服务中启用了 CORS。我按照官方文档从这个 link for Express Gateway and this link 启用 CORS 以进行身份验证服务(Express App)。这是我的代码。
快速网关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 这样的客户端)时,我从服务器返回的 Headers 可以在下图中看到。
我在浏览器控制台中收到此错误。
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
其他一切看起来都不错,尽管您可能想将“origin”添加到 allowedHeaders 列表中。
更新 我对此做了一些进一步的测试,使用这个迷你快速服务器,然后 运行 API 网关和 Docker 上的服务器(在 gateway.config.yml 中适当更改主机名),以及通过本地主机和浏览器的 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 策略条目 之前添加另一条日志消息,如下所示:
- 日志: 行动: 消息:“传入(auth):${req.method} ${req.path} 请求 IP:${req.ip} 来源 ${req.headers.origin}”
并检查原始值。如果不是 undefined,尝试在代理策略之前添加以下 response-transformer(当然,将 response-transformer 添加到可用策略列表中)。我不得不这样做一两次,但我忘记了必要的情况,所以这是在黑暗中拍摄的。
- 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"'