后端接口发送Cookies在浏览器中失效的问题排查
我尝试通过后端接口发送Cookies,Postman测试时一切正常,但在浏览器中Cookies无法正常发送。以下是相关代码:
后端代码(server.js)
import express from "express"; import mongoose from "mongoose"; import cors from "cors"; import dotenv from "dotenv"; import bodyParser from "body-parser"; import cookieParser from "cookie-parser"; import userRouter from "./routes/userRoutes.js"; import fileUpload from "express-fileupload"; dotenv.config(); const app = express(); app.use(bodyParser.json({ extended: true })); app.use(bodyParser.urlencoded({ extended: true })); app.use(cookieParser()); app.use(fileUpload()) app.use(cors({ origin: true, credentials: true })); //routes app.use('/user' , userRouter) const PORT = 5000; mongoose.connect(process.env.MONGODB_URL , {useNewUrlParser : true , useUnifiedTopology : true}) .then(() => app.listen(PORT , () => console.log(`Server is running on port : http://localhost:${PORT}`))) .catch((error) => console.log(error))
登录接口代码
export const login = async (req,res) => { try { const { email, password } = req.body; //check if empty if (!email) return res.status(400).json({ message: "Please write your Email." }); if (!password) return res.status(400).json({ message: "Please write your Password" }); //check email const user = await Users.findOne({ email }); if (!user) return res.status(400).json({ message: "This email does not exist." }); //check password const check_password = await bcrypt.compare(password, user.password); if (!check_password) return res.status(400).json({ message: "Password is incorrect." }); const refresh_token = createRefreshToken({ id: user._id }); const access_token = createAccessToken({ id: user._id }); res.cookie('refreshtoken', refresh_token, { httpOnly:false, path: '/user/refresh_token', maxAge: 30*24*60*60*1000 // 30days }); res.json({ message: "Login success.", user, access_token }); } catch (error) { return res.status(500).json({ message: error.message }); } }
前端Redux登录逻辑
export const login = (data) => async (dispatch) => { try { dispatch({ type: TYPES.NOTIFY, payload: { loading: true } }); const res = await axios.post('http://localhost:5000/user/login',data); dispatch({ type: TYPES.AUTH, payload: { token: res.data.access_token, user: res.data.user } }); localStorage.setItem('token', res.data.access_token); dispatch({ type: TYPES.NOTIFY, payload: { success: res.data.message } }) } catch (error) { dispatch({ type:TYPES.NOTIFY, payload:{ error : error.response.data.message } }) } }
补充尝试:设置axios.defaults.withCredentials后问题仍存在
export const login = (data) => async (dispatch) => { try { dispatch({ type: TYPES.NOTIFY, payload: { loading: true } }); const res = await axios.post('http://localhost:5000/user/login',data , axios.defaults.withCredentials = true); dispatch({ type: TYPES.AUTH, payload: { token: res.data.access_token, user: res.data.user } }); localStorage.setItem('token', res.data.access_token); dispatch({ type: TYPES.NOTIFY, payload: { success: res.data.message } }) } catch (error) { dispatch({ type:TYPES.NOTIFY, payload:{ error : error.response.data.message } }) } };
解决方案
1. 修正Axios的withCredentials配置方式
你的Axios配置写法错误,第三个参数应该是配置对象,而非直接赋值全局属性。正确写法二选一:
// 方式1:单个请求单独设置 const res = await axios.post('http://localhost:5000/user/login', data, { withCredentials: true }); // 方式2:全局统一设置(推荐,避免重复代码) // 在项目入口文件(如index.js)中添加 axios.defaults.withCredentials = true;
2. 明确CORS的Origin配置
当请求携带credentials时,CORS的origin不能设为true或通配符*,必须指定前端的具体域名(比如前端运行在http://localhost:3000):
// server.js中修改CORS配置 app.use(cors({ origin: "http://localhost:3000", // 替换为你的前端实际域名 credentials: true }));
3. 调整Cookie的Path范围
当前Cookie的path设为/user/refresh_token,意味着只有请求这个路径时才会携带Cookie。如果需要在其他接口也携带,建议将path改为根路径:
res.cookie('refreshtoken', refresh_token, { httpOnly: false, path: '/', // 修改为根路径 maxAge: 30*24*60*60*1000 // 30days });
4. 检查浏览器Cookie权限
部分浏览器默认限制第三方Cookie,可临时在浏览器设置中开启第三方Cookie权限测试;同时确保前后端运行在不同端口(符合跨域场景)。
内容的提问来源于stack exchange,提问作者Zain Alabdeen
相关产品推荐
相关产品推荐

