You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

后端接口发送Cookies在浏览器中失效的问题排查

问题:Postman测试Cookies正常,浏览器无法发送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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 03:10:38