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

如何在Socket.io连接时附带请求(req)以实现用户授权?

Socket.io 服务端用户授权:关联请求与Socket的实现方案

下面是几种实用的实现方式,帮你在Socket.io服务端完成用户授权,将请求(或认证信息)与Socket关联:

方法1:连接时通过auth选项传递认证令牌(推荐)

在客户端发起Socket连接时,直接携带认证令牌,服务端在握手阶段完成验证并绑定用户信息到Socket对象。

客户端代码

// 从本地存储或其他位置获取用户登录后的令牌
const authToken = localStorage.getItem('userAuthToken');
const socket = io.connect(':4000', {
  auth: {
    token: authToken
  }
});

socket.emit('trim-movie', data);

服务端代码

const jwt = require('jsonwebtoken'); // 假设使用JWT做令牌验证
const io = socket(server);

io.on("connection", (socket) => {
  // 从握手信息中提取客户端传递的认证令牌
  const { token } = socket.handshake.auth;

  try {
    // 验证令牌合法性,解析出用户信息
    const userInfo = jwt.verify(token, '你的密钥');
    // 将用户信息挂载到socket对象上,后续所有事件都可直接使用
    socket.currentUser = userInfo;

    socket.on('trim-movie', (data) => {
      // 这里可以基于socket.currentUser做权限判断
      if (socket.currentUser.permissions.includes('trim-movie')) {
        trimMovie(data);
      } else {
        socket.emit('auth-error', '无权限执行该操作');
      }
    });
  } catch (err) {
    // 令牌验证失败,直接断开连接
    socket.disconnect(true);
  }
});

方法2:利用HTTP请求的Cookie/会话信息关联请求

如果你的项目已经基于HTTP会话(比如Express Session)实现了登录认证,Socket.io连接会自动携带请求Cookie,服务端可以通过握手请求获取会话信息。

服务端代码(结合Express)

const express = require('express');
const session = require('express-session');
const app = express();
const server = require('http').createServer(app);
const io = socket(server);

// 先配置Express的会话中间件
app.use(session({
  secret: '会话密钥',
  resave: false,
  saveUninitialized: false
}));

// 自定义Socket.io中间件,关联请求与Socket
io.use((socket, next) => {
  // socket.request就是发起Socket握手的HTTP请求对象
  const req = socket.request;
  // 假设你已通过Express中间件将用户信息存入req.session.user
  if (req.session && req.session.user) {
    socket.currentUser = req.session.user;
    next(); // 验证通过,允许连接
  } else {
    next(new Error('未授权,请先登录')); // 验证失败,拒绝连接
  }
});

io.on("connection", (socket) => {
  socket.on('trim-movie', (data) => {
    // 直接使用已挂载的用户信息做授权
    trimMovie(data);
  });
});

方法3:在事件中附带认证信息(按需使用)

如果不需要在连接阶段验证,也可以在发送业务事件时附带认证令牌,服务端每次处理事件时验证。

客户端代码

const socket = io.connect(':4000');
const authToken = localStorage.getItem('userAuthToken');
// 发送事件时同时传递数据和令牌
socket.emit('trim-movie', { data, token: authToken });

服务端代码

const jwt = require('jsonwebtoken');
const io = socket(server);

io.on("connection", (socket) => {
  socket.on('trim-movie', (payload) => {
    const { data, token } = payload;
    try {
      const userInfo = jwt.verify(token, '你的密钥');
      // 验证通过后执行业务逻辑
      trimMovie(data);
    } catch (err) {
      socket.emit('auth-error', '授权失败,请重新登录');
    }
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 21:10:35