多端登录管理
createMultiDeviceManager 提供了多端登录管理能力,支持设备总数限制、同类型设备限制和溢出策略(拒绝登录或踢掉最老设备)。基于内存 Map 存储用户设备会话。
import { createMultiDeviceManager } from "@ventostack/auth";
const dm = createMultiDeviceManager({ maxDevices: 5, // 每用户最大设备数 maxPerType: 2, // 每种设备类型最大数 overflowStrategy: "kick-oldest", // 超出时踢掉最老设备});
// 用户登录const result = await dm.login("user-1", { sessionId: "sess-abc", userId: "user-1", deviceType: "web", deviceName: "Chrome / macOS", ip: "192.168.1.1",});
console.log(result.allowed); // trueconsole.log(result.kicked); // undefined(未超出限制)当设备数超出限制时,根据 overflowStrategy 决定行为:
| 策略 | 行为 |
|---|---|
kick-oldest(默认) | 按 lastActiveAt 踢掉最老的设备,返回被踢 sessionId 列表 |
reject | 直接拒绝登录,返回 { allowed: false } |
// 当 maxPerType=2 且已有 2 个 web 设备时const result = await dm.login("user-1", { sessionId: "sess-new", userId: "user-1", deviceType: "web",});
// overflowStrategy: "kick-oldest" 时// result = { allowed: true, kicked: ["sess-oldest"] }
// overflowStrategy: "reject" 时// result = { allowed: false }设备会话管理
Section titled “设备会话管理”// 注销单个设备dm.logout("user-1", "sess-abc");
// 注销用户的所有设备dm.logoutAll("user-1");
// 获取用户所有设备会话const sessions = dm.getSessions("user-1");
// 获取活跃设备数const count = dm.getActiveDeviceCount("user-1");
// 更新设备活跃时间(续期)dm.touch("user-1", "sess-abc");
// 验证会话是否有效const valid = dm.isSessionValid("user-1", "sess-abc"); // true/false| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
maxDevices | number | 5 | 每个用户的最大设备总数 |
maxPerType | number | 2 | 每种设备类型的最大设备数 |
deviceTypes | string[] | — | 允许的设备类型列表 |
overflowStrategy | "reject" | "kick-oldest" | "kick-oldest" | 超出限制时的处理策略 |
interface DeviceSession { sessionId: string; userId: string; deviceType: string; // 如 "web", "ios", "android" deviceName?: string; ip?: string; userAgent?: string; createdAt: number; lastActiveAt: number;}
interface MultiDeviceManager { login(userId: string, device: Omit<DeviceSession, "createdAt" | "lastActiveAt">): Promise<{ allowed: boolean; kicked?: string[] }>; logout(userId: string, sessionId: string): void; logoutAll(userId: string): void; getSessions(userId: string): DeviceSession[]; getActiveDeviceCount(userId: string): number; touch(userId: string, sessionId: string): void; isSessionValid(userId: string, sessionId: string): boolean;}- 设备会话基于内存 Map 存储,重启后丢失,需配合持久化 Session 一起使用
- 同类型设备限制先于总设备数限制检查,两种限制可叠加生效
kick-oldest策略按lastActiveAt排序,长时间未活跃的设备优先被踢出