73 lines
1.9 KiB
TypeScript
73 lines
1.9 KiB
TypeScript
import { Socket, Server } from "socket.io";
|
||
import { Auth } from '@d8d-appcontainer/auth';
|
||
import type { User as AuthUser } from '@d8d-appcontainer/auth';
|
||
import { APIClient } from '@d8d-appcontainer/api';
|
||
import { setupMessageEvents } from './routes_io_messages.ts';
|
||
import debug from "debug";
|
||
|
||
const log = debug('socketio:auth');
|
||
|
||
interface SetupSocketIOProps {
|
||
io: Server, auth: Auth, apiClient: APIClient
|
||
}
|
||
|
||
export interface SocketWithUser extends Socket {
|
||
user?: AuthUser;
|
||
}
|
||
|
||
// 定义自定义上下文类型
|
||
export interface Variables {
|
||
socket: SocketWithUser
|
||
auth: Auth
|
||
user: AuthUser
|
||
apiClient: APIClient
|
||
// moduleDir: string
|
||
// systemSettings?: SystemSettingRecord
|
||
}
|
||
|
||
export function setupSocketIO({ io, auth, apiClient }:SetupSocketIOProps) {
|
||
// Socket.IO认证中间件
|
||
io.use(async (socket: SocketWithUser) => {
|
||
try {
|
||
const token = socket.handshake.query.get('socket_token');
|
||
if (!token) {
|
||
log(`未提供token,拒绝连接: ${socket.id}`);
|
||
throw new Error('未授权')
|
||
}
|
||
|
||
const userData = await auth.verifyToken(token);
|
||
if (!userData) {
|
||
log(`无效token,拒绝连接: ${socket.id}`);
|
||
throw new Error('无效凭证')
|
||
}
|
||
|
||
socket.user = userData;
|
||
log(`认证成功: ${socket.id} 用户: ${userData.username}`);
|
||
} catch (error) {
|
||
log(`认证错误: ${socket.id}`, error);
|
||
}
|
||
});
|
||
|
||
io.on("connection", (socket: SocketWithUser) => {
|
||
if (!socket.user) {
|
||
socket.disconnect(true);
|
||
return;
|
||
}
|
||
|
||
console.log(`socket ${socket.id} 已连接,用户: ${socket.user.username}`);
|
||
|
||
socket.on("disconnect", (reason) => {
|
||
console.log(`socket ${socket.id} 断开连接,原因: ${reason}`);
|
||
});
|
||
|
||
const context: Variables = {
|
||
socket,
|
||
auth,
|
||
apiClient,
|
||
user: socket.user,
|
||
}
|
||
|
||
// 初始化消息路由
|
||
setupMessageEvents(context);
|
||
});
|
||
} |