MERN应用浏览器Cookie设置失败问题求助
我正在开发MERN应用,用户登录时会生成access_token和refresh_token两个令牌:access_token存入Redux状态,refresh_token计划存入浏览器Cookie。目前其他功能均正常,但Cookie仅能在Network标签页中查到,无法在Application标签页显示,已尝试多个本地浏览器。
后端代码
server.js
require('dotenv').config() const express = require('express') const app = express() const cors = require('cors') const cookieParser = require('cookie-parser') const corsOption = require('./config/corsOption') const PORT = process.env.PORT || 3500 const authHandler = require('./routes/authRoutes') app.use(cookieParser(process.env.COOKIE_SECRET)) app.use( cors({ credentials: true, origin: "http://localhost:3000", })) app.use(express.json()) app.use('/',authHandler) app.get('/',(req,res)=>{ res.status(200).json({ 'message': 'Server responding successfully.'}) }) app.all("*",(req,res) => { res.status(404).json({'message':'Not found!'}) }) app.listen(PORT , ()=>{ console.log(`Server is running in port ${PORT}`) })
登录控制器(login controller)
const jwt = require('jsonwebtoken') const dbConnections = require('../config/dbConnect') const bcrypt = require('bcrypt') const loginUser = async(req,res) =>{ try{ const database = await dbConnections() const collection = database.collection('users') const { email , password } = req.body if(!email || !password){ return res .status(400) .json({ "message": "Failed. No empty field allowed!" }) } if(!/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/.test(email)){ return res .status(404) .json({ "message": "Invalid email format!" }) } const query = { email : email } const user = await collection.findOne(query) if(!user){ return res .status(400) .json({ "message":"No user found with this email. Please signup." }) } const match = await bcrypt.compare(password,user.password) if(!match) { return res .status(400) .json({ "message":"Invalid password!" }) } const refresh_token = jwt.sign({ email:email, role: user.role }, process.env.REFRESH_TOKEN, {expiresIn: '2h'} ) const access_token = jwt.sign({ email:email, role: user.role }, process.env.REFRESH_TOKEN, {expiresIn: '15m'} ) res.cookie('refresh_token', refresh_token, { path: "/", sameSite: "none", httpOnly: true, secure: true, }) res .status(200) .json({ "access_token": access_token, "message": "Login successfully." }) }catch(err){ console.log(err) } }
前端代码
store.js
import { configureStore } from "@reduxjs/toolkit" import authSlice from "../feature/auth/authSlice" import { apiSlice } from "../app/api/apiSlice" export const store = configureStore({ reducer:{ auth : authSlice, [apiSlice.reducerPath] : apiSlice.reducer, }, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(apiSlice.middleware) })
apislice.js
import { createApi , fetchBaseQuery } from "@reduxjs/toolkit/query/react" export const apiSlice = createApi({ baseQuery: fetchBaseQuery({ baseUrl: 'http://localhost:3500' }), credentials: 'include', tagTypes: [], endpoints: builder => ({}) })
authApiSlice.js
import { apiSlice } from "../../app/api/apiSlice"; export const authApiSlice = apiSlice.injectEndpoints({ endpoints: builder =>({ login: builder.mutation({ query: ( credentials ) =>({ url : '/user/login', method: 'post', body : credentials, }) }), }) }) export const { useLoginMutation, } = authApiSlice
authSlice.js
import { createSlice } from "@reduxjs/toolkit" const initialState = { user : {}, } export const authSlice = createSlice({ name: 'auth', initialState, reducers: { logIn: (state,action) =>{ state.user = action.payload }, signUp: (credentials) =>{ }, logOut: () =>{ } } }) export const { logIn , logOut , signUp} = authSlice.actions export default authSlice.reducer
问题原因及解决方法
核心问题
本地开发使用http://localhost(非HTTPS协议),但Cookie配置中设置了secure: true——该属性要求Cookie仅能通过HTTPS传输,HTTP环境下浏览器会拒绝保存此Cookie,因此Network标签能看到响应头里的Set-Cookie,但Application标签不会显示。
具体修复步骤
动态调整Cookie的
secure和sameSite属性
在登录控制器的res.cookie配置中,根据环境变量区分开发/生产环境:res.cookie('refresh_token', refresh_token, { path: "/", sameSite: process.env.NODE_ENV === 'production' ? "none" : "lax", httpOnly: true, secure: process.env.NODE_ENV === 'production', maxAge: 2 * 60 * 60 * 1000 // 可选,与JWT过期时间保持一致 })- 生产环境(HTTPS):启用
secure: true和sameSite: "none" - 开发环境(HTTP):设置
secure: false,sameSite改为"lax"或"strict"("none"必须配合secure: true,否则浏览器会判定为无效配置)
- 生产环境(HTTPS):启用
验证配置一致性
确认后端CORS的origin与前端地址完全匹配(当前代码已设置为http://localhost:3000,无需修改),且credentials: true已开启;前端RTK Query的credentials: 'include'配置正确(当前代码已设置)。清理浏览器缓存
清除浏览器中残留的无效Cookie后,重新测试登录流程。
内容的提问来源于stack exchange,提问作者Md Mahfuz Anam Tasnim
相关产品推荐
相关产品推荐

