javascript - 如何在 CORS 中间件中读取自定义标头
问题描述
我使用CORS包创建了 CORS 中间件。这个中间件将在每次调用之前被调用。这是我的实现。
const corsMiddleware = async (req, callback) => {
const { userid } = req.headers|| req.cookies {};
let whiteList = await getWhiteListDomains(userid)
return callback(null, {
origin: whiteList,
credentials: true,
allowedHeaders: ["userid", "authorization", "content-type"]
});
};
并在路由初始化之前添加了这个中间件
app.use(cors(corsMiddleware));
app.options("*", cors(corsMiddleware));
app.get("/user", (req, res, next)=>{
// code
})
从浏览器中,我尝试将 API 调用为
axios({ method: "get", url: "http://localhost:3000/user", headers: {userId:"1234"} });
在我看到的服务器上调试时
access-control-request-headers:"userid"
在请求对象的标头中。
我无法读取自定义标题。这可能是因为我试图在 CORS 初始化之前读取自定义标头。但是,我仍然想阅读那个自定义标题。
解决方案
您的代码主要有两个问题。
第一个,更容易解决的是,您access-control-allow-origin
在设置的选项中缺少Access-Control-Allow-Headers
:
return callback(null, {
origin: whiteList,
credentials: true,
allowedHeaders: [
"access-control-allow-origin",
"authorization",
"content-type",
"userid"
]
});
第二个是最重要的,因为它与 CORS 的工作方式有关。您遇到的这个问题是 CORS 已经在飞行前OPTIONS
请求中拒绝了请愿书。它从不允许浏览器执行GET
请求。
您说您想userId
在飞行前OPTIONS
请求中读取自定义标头,但您不能。原因是飞行前OPTIONS
请求是由浏览器自动创建的,它不会使用您在 Axios 调用中设置的自定义标头。它只会为 CORS发送这些标头:
Origin // URL that makes the request
Access-Control-Request-Method // Method of the request is going to be executed
Access-Control-Request-Headers // Headers allowed in the request to be executed
因为您的自定义标头没有在飞行前发送,所以OPTIONS
当您尝试访问 的值时userId
,您会得到一个undefined
值:
const { userid } = req.headers|| req.cookies;
console.log(userid); // undefined
而且由于您使用的值在异步函数中不匹配,因此getWhiteListDomains
可能会得到另一个值,因此在 CORS 中间件选项中undefined
设置的值会导致 CORS 中间件拒绝飞行前请求。origin
undefined
OPTIONS
let whiteList = await getWhiteListDomains(userid); // userid === undefined
console.log(whitelist); // undefined
return callback(null, {
origin: whiteList, // undefined
credentials: true,
allowedHeaders: ["userid", "authorization", "content-type"]
});
我不完全确定您尝试使用自定义标头作为 CORS 检查的目标是什么,但我的建议是在处理自定义 CORS 配置时只检查Origin
标头,因为这是它的目的:限制和控制哪些 URL 可以访问您的服务器和资源。
如果您有兴趣在服务器收到的请求中创建任何类型的授权或受用户实现的限制,我建议您使用不同的自定义中间件,并且像现在尝试的那样完全不涉及 CORS。
推荐阅读
- python - 自定义 Matplotlib 图
- java - 主键上的 JPA @AutoGenerated 对嵌套实体使用父序列/自动增量
- hyperledger-fabric - 将带有 _(下划线)的织物模型转换为对流模型或普通 json/object 的最佳方法是什么
- java - 使用共享首选项将更改后的语言保存在应用程序上
- algorithm - 对大量相似向量进行分组
- c# - 场景切换触发碰撞前需要添加 3 秒延迟
- ubuntu - 如何设置 Visual Studio Code 以在 Linux 上调试 C 程序?
- python - Ctypes-无法使用 NtQueryInformationProcess 获取 PEB 地址
- react-native - 如何将多个数据的数组设置为状态
- kivy - Kivy RecycleView。附加来自另一个类的数据