我为我的Express服务器配置了以下内容:
但是对于任何不是“/user”的路由,我都会收到一个“CORS缺少允许凭据”错误,并且请求头如下:
我在其他路由中使用了一个中间件,可能会导致问题, 如果是这样的话,这里是它的代码:
我觉得我的跨域资源共享(CORS)和头盔(Helmet)配置可能设置不正确,但这是我访问的一个端点,它的响应中没有设置任何头部信息。
可能有用的是补充一下,我在/expense/expenses请求上遇到了502错误网关和严格的来源-跨源引荐策略。
最后,我正在使用rtk query来进行这些API调用,基本查询如下:
环境变量与服务器URL匹配,所以没有问题,前端登录组件会设置cookie,如下所示:
import express from "express";
import bodyParser from "body-parser";
import mongoose from "mongoose";
import cors from "cors";
import dotenv from "dotenv";
import helmet from "helmet";
import morgan from "morgan";
import cookieParser from "cookie-parser";
import categoryRoutes from "./routes/category.js";
import subCategoryRoutes from "./routes/subCategory.js";
import expenseRoutes from "./routes/expense.js";
import userRoutes from "./routes/user.js";
import { authMiddleware } from "./middleware/authMiddleware.js";
dotenv.config();
const app = express();
app.use(cookieParser());
app.use(express.json());
app.use(helmet());
app.use(helmet.crossOriginResourcePolicy({ policy: "cross-origin" }));
app.use(morgan("common"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(
cors({
origin: *********************,
credentials: true,
})
);
app.use("/category", authMiddleware, categoryRoutes);
app.use("/subCategory", authMiddleware, subCategoryRoutes);
app.use("/expense", authMiddleware, expenseRoutes);
app.use("/user", userRoutes);
const PORT = process.env.PORT || 9000;
mongoose
.connect(process.env.MONGO_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(async () => {
app.listen(PORT, () => {
console.log(`Server running on port: ${PORT}`);
});
})
.catch((error) => {
console.log(`${error} connecting to DB`);
});
但是对于任何不是“/user”的路由,我都会收到一个“CORS缺少允许凭据”错误,并且请求头如下:
Accept
*/*
Accept-Encoding
gzip, deflate, br
Accept-Language
en-US,en;q=0.5
Connection
keep-alive
Cookie
jwt=*************************
Host
*************************
Origin
https://*********************
Referer
https:/**********************/
Sec-Fetch-Dest
empty
Sec-Fetch-Mode
cors
Sec-Fetch-Site
cross-site
TE
trailers
User-Agent
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0
我在其他路由中使用了一个中间件,可能会导致问题, 如果是这样的话,这里是它的代码:
import jwt from "jsonwebtoken";
export const authMiddleware = async (req, res, next) => {
const { id, token } = req.cookies;
console.log(id, token);
try {
if (id) {
req.userId = id;
res.setHeader(
"Access-Control-Allow-Origin",
"**************************"
);
res.setHeader("Access-Control-Allow-Credentials", true);
next();
}
if (token) {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
if (decoded) {
const userId = decoded.id;
req.userId = userId;
res.setHeader(
"Access-Control-Allow-Origin",
"**************************"
);
res.setHeader("Access-Control-Allow-Credentials", true);
next();
}
}
} catch (error) {
throw new Error("Not authorized!");
}
};
我觉得我的跨域资源共享(CORS)和头盔(Helmet)配置可能设置不正确,但这是我访问的一个端点,它的响应中没有设置任何头部信息。
router.get("/expenses/", async (req, res) => {
const userId = req.userId;
console.log(userId);
try {
const expenses = await Expense.find({
userId: userId,
})
.populate("subCategory")
.populate("category")
.exec();
const mappedExpenses = expenses.map((expense) => ({
id: expense._id,
date: expense.date,
price: expense.price,
userId: expense.userId,
category: expense.category.name,
subCategory: expense.subCategory.name,
}));
console.log("user expenses: ", mappedExpenses);
res.status(200).json(mappedExpenses);
} catch (error) {
res.status(404).json({ message: error.message });
}
});
可能有用的是补充一下,我在/expense/expenses请求上遇到了502错误网关和严格的来源-跨源引荐策略。
最后,我正在使用rtk query来进行这些API调用,基本查询如下:
baseQuery: fetchBaseQuery({baseUrl: import.meta.env.VITE_BASE_URL, credentials: 'include'}),
环境变量与服务器URL匹配,所以没有问题,前端登录组件会设置cookie,如下所示:
loginUser(values)
.unwrap()
.then((res) => {
console.log(res._id);
setCookie("id", res._id, {
path: "/",
sameSite: "none",
secure: true,
});
toast.success("logged in!");
navigate("/dashboard", { replace: true });
})
.catch((e) => {
console.log(e);
});
cors
模块与自己编写的setHeader
调用混合使用,用于处理Access-Control-etc
头部。这样只会让事情变得更加混乱。 - Quentincors
模块与自己编写的setHeader
调用混合使用,用于处理Access-Control-etc
头部。这样只会让事情变得更加混乱。 - Quentin