Node.js 单设备登录(SDL)
SDL(Single Device Login)允许同一时间只在一台设备上登录,新设备登录时旧设备被挤下线。
应用场景
- 视频影音(防账号共享)
- 社交媒体(防未授权访问)
- 在线支付(增强安全)
- 邮箱通讯(保护隐私)
实现思路
使用 socket.io + 浏览器指纹 + Redis:
js
// 数据结构
{
userId: {
socket: ws实例,
fingerprint: '浏览器指纹'
}
}完整流程
1. 用户登录 → 生成 JWT token
→ 记录 fingerprint(用户代理 + 屏幕分辨率等)
→ 建立 socket.io 连接
2. 用户在新设备登录
→ 查询 Redis 发现已有 fingerprint 且不同
→ 通过 socket.io 向旧设备发送 'kickout' 事件
→ 旧设备收到 → 清除本地 token → 提示"已被挤下线"
→ 更新 Redis 记录为新设备信息核心代码
js
import { Server } from 'socket.io'
const userSockets = {} // userId → { socket, fingerprint }
io.on('connection', (socket) => {
// 登录时注册
socket.on('login', ({ userId, fingerprint }) => {
// 检查是否已有其他设备登录
if (userSockets[userId] && userSockets[userId].fingerprint !== fingerprint) {
// 通知旧设备下线
userSockets[userId].socket.emit('kickout', '您的账号在其他设备登录')
}
// 记录新设备
userSockets[userId] = { socket, fingerprint }
})
})浏览器指纹(简易版)
js
const fingerprint = navigator.userAgent + screen.width + screen.height生产环境可用
fingerprint.js等专业库生成更精确的指纹。