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

如何修改Node.js登录代码实现多设备同时登录

实现Node.js多设备同时登录不互踢的修改方案

当前代码在用户新设备登录时,会通过User.updateOne覆盖用户表中的auth_token字段,导致旧设备的token失效。要实现多设备同时登录,需要调整token的存储和验证逻辑,具体修改如下:


核心问题分析

原代码的问题在于:

  • 登录时将新token写入User表的auth_token字段,直接覆盖旧token,导致旧设备无法通过身份验证
  • 仅依赖User表的单个token做身份校验,天然不支持多设备并存

修改步骤

1. 删除User表更新auth_token的代码

登录过程中不再更新User表的auth_token字段,每个设备的token独立存储在LoginInfo表中即可。

找到并删除这段代码:

await User.updateOne({_id:user_data._id}, {
  $set:{
    auth_token:token
  }
})

2. 重构token验证逻辑(关键)

原验证逻辑应该是对比请求token与User表的auth_token,现在需要改为从LoginInfo表中校验token有效性:

  • 解析JWT获取用户ID(sub字段)
  • 在LoginInfo表中查询该用户对应的、未过期且未被注销的token记录
  • 存在匹配记录则验证通过

示例验证中间件代码:

async function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];

  if (!token) return res.sendStatus(401);

  try {
    // 这里要和登录时用的密钥一致
    const jwtkey = req.user?.user_id?.split("/")[0] || /* 从用户信息获取密钥的逻辑 */;
    const payload = jwt.verify(token, jwtkey);
    
    // 校验token是否在LoginInfo中有效
    const validLogin = await LoginInfo.findOne({
      user_id: payload.sub,
      auth_token: token,
      // 可选:和JWT过期时间同步,自动清理过期token
      expires_at: { $gt: new Date() }
    });

    if (!validLogin) return res.sendStatus(401);

    req.user = payload;
    next();
  } catch (err) {
    return res.sendStatus(403);
  }
}

3. 可选:给LoginInfo添加过期时间字段

为了自动管理过期token,创建LoginInfo时可以添加expires_at字段,和JWT的过期时间保持一致:

// 修改登录时创建LoginInfo的代码
await LoginInfo.create({
    user_id: user_data.user_id,
    sys_info: sys_info ? sys_info.split('"').join("") : "NA",
    browser_info: browser_info ? browser_info.split('"').join(" ") : "NA",
    ip_address: ipaddr,
    timestamp: time,
    access_token: access_token,
    auth_token: token,
    expires_at: new Date(Date.now() + 24 * 60 * 60 * 1000) // 24小时后过期
});

4. 可选:支持用户手动注销设备

添加接口让用户主动注销某台设备的token:

async function logoutDevice(req, res) {
  const { token } = req.body; // 或者让用户选择设备ID来注销
  await LoginInfo.deleteOne({ auth_token: token });
  res.json({ status: 200, message: "设备已成功注销" });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 13:22:15