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

Electron应用中登录后Cookie无法保存问题及修复咨询

Electron中JWT Cookie无法存储的解决方案

问题根源

Electron的Cookie管理机制和普通浏览器存在差异:默认会话配置、跨域规则、Cookie属性要求都可能导致后端设置的Cookie无法被持久化。需要针对Electron的特性调整后端Cookie配置,并在Electron主进程中做相应设置。


一、修改后端Cookie配置

你的代码中存在两个关键问题:

  1. Cookie选项的expiresIn是错误属性名,正确应为expires
  2. 缺少Electron需要的SameSite、secure、path属性,这些会影响Cookie的存储规则

修改后的后端代码:

const jwt = require('jsonwebtoken')
const db = require('path_to_database')
const bcrypt = require('bcryptjs')

const login = async(req, res) => {
  const { username, password } = req.body;
  if (!username || !password) {
    return res.json({
      status: 'error',
      error: '请输入用户名和密码'
    })
  }
  
  try {
    // 改用promise风格查询,避免回调嵌套
    const [result] = await db.promise().query('SELECT * FROM users WHERE username = ?', [username]);
    if (!result.length || !await bcrypt.compare(password, result[0].password)) {
      return res.json({
        status: 'error',
        error: '用户名或密码错误'
      })
    }

    const token = jwt.sign(
      { id: result[0].id },
      process.env.JWT_SECRET,
      { expiresIn: process.env.JWT_EXPIRES }
    )

    const cookieOption = {
      expires: new Date(Date.now() + process.env.COOKIE_EXPIRES * 24 * 60 * 60 * 1000),
      httpOnly: true,
      // 生产环境跨域需设为None,同时开启secure;开发环境用Lax
      sameSite: process.env.NODE_ENV === 'production' ? 'None' : 'Lax',
      secure: process.env.NODE_ENV === 'production',
      path: '/' // 确保Cookie在全站生效
    }

    res.cookie('userRegistered', token, cookieOption)
    return res.json({
      status: 'success',
      success: '用户登录成功'
    })
  } catch (err) {
    console.error(err);
    return res.json({
      status: 'error',
      error: '服务器内部错误'
    })
  }
}

二、配置Electron主进程

在Electron的主进程中,需要确保会话持久化,并根据开发/生产环境调整安全规则:

const { BrowserWindow, session } = require('electron');
const path = require('path');

function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      contextIsolation: true, // 开启上下文隔离,提升安全性
      preload: path.join(__dirname, 'preload.js'),
      partition: 'persist:my-app-session', // 持久化会话,确保Cookie重启后不丢失
      // 开发环境可临时关闭webSecurity,避免跨域Cookie限制;生产环境必须开启
      webSecurity: process.env.NODE_ENV === 'production',
      allowRunningInsecureContent: process.env.NODE_ENV !== 'production'
    }
  });

  // 加载你的站点
  mainWindow.loadURL('http://localhost:3000');
}

// 可选:手动设置Cookie(如果后端设置仍不生效)
const { ipcMain } = require('electron');
ipcMain.handle('set-auth-cookie', async (event, token) => {
  try {
    await session.defaultSession.cookies.set({
      name: 'userRegistered',
      value: token,
      url: 'http://localhost:3000', // 必须和你的后端/站点URL一致
      expires: Date.now() + 7 * 24 * 60 * 60 * 1000,
      httpOnly: true,
      path: '/'
    });
    return true;
  } catch (err) {
    console.error('设置Cookie失败:', err);
    return false;
  }
});

如果用手动设置Cookie的方式,需要在preload.js中暴露IPC接口给前端:

const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electronAPI', {
  setAuthCookie: (token) => ipcRenderer.invoke('set-auth-cookie', token)
});

前端登录成功后直接调用该接口:

axios.post('/login', { username, password })
  .then(res => {
    if (res.data.status === 'success') {
      window.electronAPI.setAuthCookie(res.data.token);
    }
  });

关键注意事项

  • URL一致性:Electron设置Cookie时,url必须和请求的域名/端口完全一致,否则Cookie不会被存储
  • 环境区分:开发环境下secure必须设为false(因为用http协议),生产环境必须设为true配合SameSite: None
  • 会话持久化:必须设置partition: 'persist:xxx',否则Electron重启后Cookie会丢失

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 00:39:17