如何在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
相关产品推荐
相关产品推荐

