自定义 headers 被 CORS 阻止

Custom headers blocked by CORS

我正在使用 Angular2+ 应用向 NodeJS API 发出请求。

只要我不添加自定义 headers,就会进行调用,并且会根据我的要求得到响应。但是,如果我使用 interceptor 手动设置 header,则会导致错误。

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at [api_url]. (Reason: CORS request did not succeed)

这是登录方法的结果,我首先调用没有 headers 的服务器,然后添加 headers 并再次调用服务器。

第一个POST方法的header

和第二种POST方法之一

两个自定义 header 由 Angular 中的拦截器添加如下

...
const cloned = req.clone({
  headers: req.headers.set("Authorization", "Bearer " + idToken)
                      .set("X-QWEMP-data", encrypted)
});
req = cloned
...

当我删除它们时,路径已到达,但当然会因为缺少数据而抛出错误。

现在,对于我的 API,我尝试了很多配置来允许自定义 header。首先是如下手动添加 headers 和 return 预检选项(不记得我是怎么做的,但它是这样的)

app.use((req,res,next) => {
  set.headers('Access-Control-Allow-Origin','*')
  set.headers('Access-Control-Allow-Headers','Authorization,X-QWEMP-data')
  if (req.method === 'OPTIONS') {
    res.send()
    return;
  }else{
    next()
    return;
  }
})

然后,我使用 cors 库和默认配置,只需添加 app.use(cors())

最后,我尝试在 cors 中添加自定义配置,如下所示(整个 app.js 文件)

require('dotenv').config()
const express = require('express');
const indexRouter = require('../routes/index');
const bodyParser = require('body-parser')
const cors = require('cors')
const morgan = require('morgan');

const app = express();

app.use(cors({
  methods:'GET,POST,PUT,DELETE,OPTIONS',
  allowedHeaders:'Authorization,X-QWEMP-data,Content-Type,[and all the already accepted headers in case]',
  exposedHeaders:'[same as allowedHeaders]',
  credentials:true,
  preflightContinue:true
})

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

app.use(morgan('tiny'));

app.use('/', indexRouter)

app.listen(3000, () => {
  console.log('Server listening on port 3000.')
})

编辑

网络选项卡中的请求屏幕

第一个选项

第一个POST

第二个选项

第二个POST

添加自定义 header 会导致浏览器要求 pre-flight 用于跨源请求。这意味着浏览器将向您的服务器发送一个相同路径的 OPTIONS 请求,并且它必须从该 OPTIONS 请求返回一个带有适当 headers 的 2xx 响应,否则它不会发送实际的 follow-on 请求.

根据我在 CORS 模块的文档中了解到的内容(并通过小实验验证),当您设置时:

preflightContinue: true

您要告诉 CORs 中间件跳过该 OPTIONS 请求并将其发送到其他请求处理程序。该文档特别指出:“将 CORS 预检响应传递给下一个处理程序”。由于您没有针对该 pre-flight 请求的其他请求处理程序,您的服务器将生成 404 并且浏览器将看到 pre-flight 失败,因此您的请求将失败。

所以,首先要尝试的是改为:

preflightContinue: false

如果仍然无效,请显示 Chrome 调试器网络选项卡中显示的确切请求。它将准确显示浏览器为 pre-flight 发送的内容,并将准确显示您的服务器响应该内容返回的内容。

问题最终不是关于 CORS,即使它抛出错误。

事实上,由于未知原因,JWT 太长了。我使用“Burp Suite”拦截请求并在转发器中添加请求以重新发送它们并使用自定义值进行测试。

所以弄清楚这一点,我需要更新 jsonwebtoken 库使用的密钥以使用较小的密钥对 JWT 进行签名,这样 JWT 就更小了。