微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

即使在 Express 和 Express 网关上启用 CORS 后仍受 CORS 策略限制

如何解决即使在 Express 和 Express 网关上启用 CORS 后仍受 CORS 策略限制

我使用 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 这样的客户端)时,我从服务器返回的标头如下图所示。

The Headers I get from the server

我在浏览器控制台中收到此错误

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 列表中。

更新 我已经对此做了一些进一步的测试,使用这个迷你快递服务器,然后在 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"'

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。