https://api.ikhlaas.pk
上。 在开发(Localhost)中,前端在端口3000上运行,后端在端口5000上运行。 我正在使用cookie进行身份验证。 问题✅在Local主机中:当前端和后端在Localhost上运行时,cookie会正确发送,并且受保护的API请求按预期工作。
❌在生产中:当前端在https://ikhlaas.pk上时,后端在
Https://api.ikhlaas.pk上时,cookies并未发送,导致401个未经授权的错误。 即使我尝试通过Localhost前端通过其域访问已部署的后端仍然相同的错误。 步骤繁殖 转到Https://ikhlaas.pk/login
并登录: 电子邮件:[电子邮件保护]
密码:纳鲁 登录后,请访问Https://ikhlaas.pk/dashboard/orders并在DevTools中选中“网络”选项卡。
您会看到API请求失败,因为cookie不包含在请求标题中。
我的后端CORS和Cookie代码的样子。
const allowedOrigins = [
"http://localhost:3000",
"http://localhost:3001",
"https://ikhlaas.pk",
];
const corsOptions = {
origin: function (origin, callback) {
// Check if the origin is in the allowed list or if there is no origin (like in some cases of server-to-server requests)
if (allowedOrigins.indexOf(origin) !== -1 || !origin) {
callback(null, true);
} else {
callback(new Error("Not allowed by CORS"));
}
},
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
credentials: true, // Allow credentials (cookies, authorization headers, TLS client certificates)
};
// Use the CORS middleware with the configured options
app.use(cors(corsOptions));
export const loginUser = async (req, res) => {
try {
const user = await User.findOne({ email: req.body.email });
const tokenExpiry = new Date(Date.now() + 24 * 60 * 60 * 1000);
if (!user) {
return res.status(401).json({
status: "error",
message: "User not found please create account",
});
}
const hashPassword = CryptoJS.AES.decrypt(
user.password,
process.env.PASS_SEC
);
const originalPassword = hashPassword.toString(CryptoJS.enc.Utf8);
originalPassword !== req.body.password &&
res.status(401).json("Wrong credentials!");
const accessToken = jwt.sign(
{
id: user.id,
isAdmin: user.admin,
},
process.env.JWT_SEC,
{ expiresIn: "24h" }
);
const { password, ...others } = user._doc;
if (req.cookies[`${user._id}`]) {
req.cookies[`${user._id}`] = "";
}
res.cookie(String(user._id), accessToken, {
expires: tokenExpiry,
httpOnly: true,
secure: true,
sameSite: "none",
domain: ".ikhlaas.pk",
});
res.status(201).json({ ...others, accessToken, admin: user.admin });
} catch (err) {
res.status(500).json(err);
}
};
trontend API调用代码
async function makeGetRequest(
url: string,
config: AxiosRequestConfig<any> = {},
withToken = false
): Promise<AxiosResponse | undefined> {
try {
const response = await apiClient.get(url, {
...config,
// withCredentials: true,
withCredentials: withToken ? true : false,
});
return response;
} catch (error) {
if (axios.isAxiosError(error) && error.response) {
return Promise.reject(error.response);
}
return Promise.reject(error);
}
}
const apiClient = axios.create({
baseURL: getUrl(),
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
withCredentials: true,
});
export function getUrl() {
return "https://api.ikhlaas.pk/api";
}