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

Express后端通过Axios无法向React前端传递Cookie求助

问题描述

Express后端设置JWT Cookie后,React前端通过Axios请求无法接收该Cookie,但用Thunder Client测试时Cookie可正常设置。已配置cors、cookie-parser,且开启Chrome第三方Cookie,排查多日未解决。

后端代码

const express = require("express");
// const storiesRouter = require("./routes/storiesRouter")
// const postsRouter = require("./routes/postsRouter");
// const usersRouter = require("./routes/usersRouter");
const cors = require("cors");
const cookieParser = require("cookie-parser");
const validator = require("validator");
const bcrypt = require("bcryptjs");

const userSchema = mongoose.Schema({
    name: {
      type: String,
      required: [true, "Name is required"],
    },
    email: {
      type: String,
      required: [true, "Email is required"],
      unique: true,
      lowercase: true,
      validate: [validator.isEmail, "Provide Valid email"],
    },
    img: {
      data: Buffer,
      contentType: String,
    },
    role: {
      type: String,
      enum: ["user", "lead-guide", "admin"],
      default: "user",
    },
    password: {
      type: String,
      required: [true, "Password is required"],
      minlength: 8,
      select: false,
    },
    passwordConfirm: {
      type: String,
      required: [true, "Confirm Password is required"],
      validate: {
        //Only works on create() or save()
        validator: function(el) {
          return el === this.password;
        },
        message: "Password are not same",
      },
    },
    passwordChangedAt: {
      type: Date,
    },
    passwordResetToken: String,
    passwordResetExpires: Date,
    active: {
      type: Boolean,
      default: true,
      select: false,
    },
  });
const User = mongoose.model("User", userSchema);

const app = express();

// cookieParser middleware
app.use(cookieParser());

app.use(
  cors({
    origin: "http://localhost:3001",
    credentials: true,
  })
);

app.use(express.json());

app.use("/api/v1/users/login", async (req, res, next) => {
  console.log("body", req.body);
  const email = req.body.email;
  const password = req.body.password;
  console.log(email, password);
  if (!email || !password) {
    res.status(400).json({
      status: "fail",
      message: "Please provide email and password",
    });
  }
  const user = await User.findOne({ email }).select("+password");

  if (!user || !(await user.correctPassword(password, user.password))) {
    res.status(401).json({
      status: "fail",
      message: "Incorrect email and password",
    });
  }
  const token = signToken(user._id);
  req.user = user;
  console.log(token);
  res.cookie("jwt", token, { httpOnly: true, secure: false });
  res.status(200).json({
    status: "success",
    token,
  });
  console.log("res", res);
});

const signToken = (id) => {
  return jwt.sign({ id }, process.env.JWT_SECRET, {
    expiresIn: process.env.JWT_EXPIRES_IN,
  });
};

前端Axios代码

const LoginFetch = async (methods, dataurl, loginInfo) => {
  let data = {};
  let fetchError = null;

  await axios(
    {
      method: "POST",
      url: "http://localhost:3000/api/v1/users/login",
      data: { email: loginInfo.email, password: loginInfo.password },
    },
    {
      withCredentials: true,
      headers: {
        "Access-Control-Allow-Origin": "*",
        "Content-Type": "application/json",
      },
    }
  )
    .then((dataRec) => {
      data = dataRec;
    })
    .catch((err) => {
      fetchError = err;
    });
  return data;
};

解决步骤

1. 修正前端Axios配置参数位置

withCredentials配置被错误放在了第二个参数中,Axios的标准调用格式是axios(configObject),所有配置项需统一放在同一个对象内。修改后的代码:

const LoginFetch = async (methods, dataurl, loginInfo) => {
  let data = {};
  let fetchError = null;

  await axios({
      method: "POST",
      url: "http://localhost:3000/api/v1/users/login",
      data: { email: loginInfo.email, password: loginInfo.password },
      withCredentials: true, // 移到主配置对象内
      headers: {
        "Content-Type": "application/json",
      },
    })
    .then((dataRec) => {
      data = dataRec;
    })
    .catch((err) => {
      fetchError = err;
    });
  return data;
};

2. 后端补充Cookie的SameSite属性

在设置Cookie时添加sameSite属性,确保跨域场景下Cookie能正常发送:

res.cookie("jwt", token, { 
  httpOnly: true, 
  secure: false, // 开发环境设为false,生产HTTPS环境需改为true
  sameSite: "Lax" // 开发环境用Lax,严格跨域场景可设为None(需配合secure: true)
});

3. 移除前端不必要的请求头

Access-Control-Allow-Origin是后端返回的响应头,前端请求中添加该头无效且可能引发冲突,直接删除。


内容的提问来源于stack exchange,提问作者Aditya Bhatnagar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:44:51