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

如何在React中通过fetch API存储Express服务器发送的JWT Cookie?

我用React、Express和MongoDB开发注册表单,已实现POST请求并将用户数据存入数据库,但数据保存后,无法通过res.cookie('jwt',token)在浏览器中存储JWT令牌。

React表单代码

type Props = {
    children: React.ReactNode;
};
export const SignupLayout = ({ children }: Props) => {
    const user = {
        email: 'alexy@gmail.com',
        username: 'alexladies',
        password: 'pasrfsfsdfgfdsd',
        securityQuestion: "father's name",
        securityAnswer: 'jhon',
        joinedDate: '12-12-2023',
    };
     

    const handleSignup = async (event: React.SyntheticEvent) => {
        event.preventDefault();

        // 问题出在这里
        await fetch('http://localhost:3000/signup', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(user),
        })
            .then((reponse) => reponse.json())
            .then((json) => console.log(json))
            .catch((err) => console.log(err));
    };
    return (
        <form
            onSubmit={handleSignup}
            method='post'
            action='/signup'
            className='sm:px-20 md:w-2/3 md:px-12 lg:w-1/2 lg:px-4 lg:my-4 xl:mt-16 xl:w-1/3 xl:px-16 mx-auto bg-white rounded-2xl py-10 text-center  '
        >
            {children}
        </form>
    );
};

Express服务器代码

const User = require('../../models/user');
const { handleError } = require('./error');
const { createToken } = require('../utils/token');

const getSignup = (req, res) => {
    // 该接口可成功在浏览器存储Cookie
    res.cookie('name', 'value');
    res.send('ok');
};

const postSignup = async (req, res) => {
    // 该接口无法在浏览器存储Cookie!
    const {
        email,
        password,
        username,
        securityQuestion,
        securityAnswer,
        joinedDate,
    } = req.body;

    const user = new User({
        email,
        password,
        username,
        securityQuestion,
        securityAnswer,
        joinedDate,
    });

    await user
        .save()
        .then(() => res.cookie('jwt', createToken(user._id)))
        .then(() => res.status(200).json(user._id))
        .catch((err) => {
            res.status(400).json(handleError(err));
        });
};

module.exports = { getSignup, postSignup };

我尝试在fetch请求中添加credentials:'include',但未生效。

截图

Cookie存储失败截图


解决方法

  1. 配置CORS允许凭证
    Express需安装并配置cors包,指定允许的源(不能用*,否则浏览器会拒绝携带Cookie):

    const cors = require('cors');
    app.use(cors({
        origin: 'http://localhost:你的React端口', // 例如React运行在3001则填此地址
        credentials: true
    }));
    
  2. 修正Fetch的凭证配置
    确保credentials属性与method、headers同级,正确配置:

    await fetch('http://localhost:3000/signup', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        credentials: 'include',
        body: JSON.stringify(user),
    })
    
  3. 完善Cookie属性设置
    给res.cookie添加必要属性,确保Cookie能被浏览器正确存储:

    res.cookie('jwt', createToken(user._id), {
        httpOnly: true, // 防XSS攻击,建议添加
        secure: process.env.NODE_ENV === 'production', // 生产环境启用(需HTTPS)
        sameSite: 'lax', // 或根据需求设为'none'(需配合secure=true)
        maxAge: 24 * 60 * 60 * 1000 // 设置Cookie过期时间,例如1天
    });
    
  4. 优化Promise链逻辑
    res.cookie是同步操作,无需用then链式调用,改用更清晰的async/await写法:

    try {
        const savedUser = await user.save();
        res.cookie('jwt', createToken(savedUser._id), /* 上述Cookie属性 */);
        res.status(200).json(savedUser._id);
    } catch (err) {
        res.status(400).json(handleError(err));
    }
    

内容的提问来源于stack exchange,提问作者Ala Eddine Menai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 11:05:19