简体   繁体   English

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

[英]Restricted by CORS policy even after enabling CORS on Express and Express gateway

I'm using Express Gateway to proxy my microservices.我正在使用Express Gateway来代理我的微服务。 I'm hitting the gateway from my react app with Axios .我正在使用react从我的Axios应用程序访问网关。 However, the call gets restricted by the CORS Policy .但是,调用受到CORS Policy的限制。 I have enabled CORS in the express gateway and also on my authentication service.我在快速网关和我的身份验证服务中启用了 CORS。 I followed the official documentation to enable the CORS from this link for Express Gateway and this link for authentication service(Express App).我按照官方文档从这个链接启用 CORS 用于 Express Gateway 和这个链接用于身份验证服务(Express App)。 Here is how I have the code.这是我的代码。

Express Gateway config.yml快速网关配置.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

Authentication Service app.js身份验证服务 app.js

const cors = require('cors');
// Enabling CORS
const corsOptions = {
  origin: '*',
  methods: ['POST', 'GET', 'PATCH', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization']
}
app.use(cors(corsOptions));

The Headers I get back from the server when I try with Insomnia (a client like Postman) can be seen in the below picture.当我尝试使用 Insomnia(像 Postman 这样的客户端)时,我从服务器返回的标头如下图所示。

我从服务器获得的标头

I get this error in the browser console.我在浏览器控制台中收到此错误。

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.

I'm not sure what I'm missing.我不确定我错过了什么。 Please let me know if you need anything else, I'd be quick to provide.如果您还需要什么,请告诉我,我会尽快提供。 Each and every attempt that tries to explain what's wrong with my case is really appreciated.非常感谢每一次试图解释我的案例有什么问题的尝试。

EDIT: Adding the API call snippet编辑:添加 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);

Your "methods" definition is incorrect.您的“方法”定义不正确。 It needs to be in the form of a YAML array:它需要采用 YAML 数组的形式:

methods: [ "HEAD", "PUT", "PATCH", "POST", "DELETE" ]

Or或者

methods:
- "HEAD"
- "PUT"
- "PATCH"
- "POST"
- "DELETE"

Or或者

methods:
- HEAD
- PUT
- PATCH
- POST
- DELETE

Everything else looks okay, although you may want to add "origin" to the list of allowedHeaders.其他一切看起来都不错,尽管您可能希望将“来源”添加到 allowedHeaders 列表中。

Update I have done some further testing on this, using this mini express server, then run the API gateway and server on Docker (with appropriate hostname changes in gateway.config.yml), and everything works as I expect with testing via curl from localhost and also from the browser.更新我已经对此做了一些进一步的测试,使用这个迷你快递服务器,然后在 Docker 上运行 API 网关和服务器(在 gateway.config.yml 中进行适当的主机名更改),一切正常,通过 ZF6E57C9DE5351E435FEB0D 进行测试也来自浏览器。

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}`)
})

The only other thing I can suggest is to add another log message before the cors policy entry in gateway.config.yml like this:我唯一可以建议的另一件事是在 gateway.config.yml 中的 cors 策略条目之前添加另一条日志消息,如下所示:

- log: action: message: "incoming (auth): ${req.method} ${req.path} requesting IP: ${req.ip} origin ${req.headers.origin}" - 日志:操作:消息:“传入(身份验证):${req.method} ${req.path} 请求 IP:${req.ip} 来源 ${req.headers.origin}”

and check the value of origin.并检查原产地的价值。 If it is not undefined, try adding the following response-transformer before the proxy policy (adding response-transformer to the list of available policies, of course).如果它不是未定义的,请尝试在代理策略之前添加以下响应转换器(当然,将响应转换器添加到可用策略列表中)。 I have had to do this once or twice but I forget the circumstances where it was necessary, so this is a shot in the dark.我不得不这样做一两次,但我忘记了必要的情况,所以这是在黑暗中拍摄的。

  - 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"'

if you have methods in auth apiEndpoints then removed methods from apiEndpoints: auth ----methods: 'GET,POST,PUT' ---- and it worked for me..如果您在 auth apiEndpoints 中有方法,则从 apiEndpoints 中删除方法: auth ----methods: 'GET,POST,PUT' ---- 它对我有用..

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM