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

如何在Socket.io连接逻辑中使用登录接口返回的JWT accessToken

实现方案

1. 优化登录接口JWT生成逻辑

你当前的JWT签名直接传入email字符串,建议改为传入结构化payload,也可以补充过期时间提升安全性,修改后代码如下:

router.post("/", async (req, res) => {
  const { email, password } = req.body;
  console.log(email, password);

  try {
    if (email && password) {
      // 改为传入payload对象,可根据需要添加自定义字段,补充过期时间
      const accessToken = jwt.sign(
        { email: email }, 
        process.env.TOKEN_SECRET,
        { expiresIn: '24h' }
      )
      res.json(accessToken);
    } else res.sendStatus(400);
  } catch (error) {
    res.sendStatus(500);
  }
});

2. 前端传递accessToken

前端登录成功拿到服务端返回的accessToken后,选择以下任意一种方式传递给Socket.io服务:

  • 方式1:建立Socket连接时携带(适合全局校验身份,身份非法直接拒绝连接)
    前端代码示例:
    // 从本地存储(比如localStorage)取到登录返回的token
    const accessToken = localStorage.getItem('accessToken')
    // 建立连接时放在query参数中
    const socket = io('你的Socket服务地址', {
      query: { accessToken: accessToken }
    })
    
  • 方式2:触发joinRoom事件时携带(适合仅在加入房间时校验身份)
    前端代码示例:
    const accessToken = localStorage.getItem('accessToken')
    socket.emit('joinRoom', { 
      username: '你的用户名', 
      room: '目标房间号',
      accessToken: accessToken 
    })
    

3. 后端Socket.io侧获取并校验token

需要先引入jsonwebtoken模块做token合法性校验,避免伪造的token被使用:

  • 对应方式1的后端处理代码:
    const jwt = require('jsonwebtoken')
    io.on('connection', socket => {
      // 连接建立时先校验token
      const accessToken = socket.handshake.query.accessToken
      try {
        // 校验token合法性,解析出payload
        const payload = jwt.verify(accessToken, process.env.TOKEN_SECRET)
        // 可将解析后的信息挂载到socket对象上方便后续使用
        socket.userPayload = payload
      } catch (err) {
        // token非法直接断开连接
        socket.disconnect()
        return
      }
    
      socket.on('joinRoom', ({ username, room }) => {
        // 直接取之前挂载的token或者解析后的payload
        const user = userJoin(socket.id, username, room, accessToken);
        socket.join(user.room);
      })
    })
    
  • 对应方式2的后端处理代码:
    const jwt = require('jsonwebtoken')
    io.on('connection', socket => {
      socket.on('joinRoom', ({ username, room, accessToken }) => {
        try {
          // 先校验token合法性
          jwt.verify(accessToken, process.env.TOKEN_SECRET)
        } catch (err) {
          // 校验失败返回错误信息,不允许加入房间
          socket.emit('error', { msg: '身份校验失败,请重新登录' })
          return
        }
        const user = userJoin(socket.id, username, room, accessToken);
        socket.join(user.room);
      })
    })
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 01:36:08