feat: 修复 WebSocket 越权与 AI 流 SSRF

This commit is contained in:
weijuesen
2026-08-14 00:45:22 +08:00
parent 1a29def480
commit 839ba91354
17 changed files with 614 additions and 136 deletions
+19 -5
View File
@@ -1,5 +1,6 @@
import Taro from '@tarojs/taro';
import { getWsUrl } from '@/api/config';
import { get } from '@/api/request';
type MessageHandler = (data: unknown) => void;
@@ -7,19 +8,20 @@ class WebSocketManager {
private connected: boolean = false;
private handlers: Map<string, Set<MessageHandler>> = new Map();
private token: string = '';
private ticket: string = '';
private reconnectAttempts: number = 0;
private maxReconnectAttempts: number = 5;
private reconnectTimer: ReturnType<typeof setTimeout> | null = null;
private isManualClose: boolean = false;
connect(token: string): void {
async connect(token: string): Promise<void> {
this.token = token;
this.isManualClose = false;
this.doConnect();
await this.refreshTicketAndConnect();
}
private doConnect(): void {
if (!this.token) {
if (!this.token || !this.ticket) {
console.warn('[WS] 无 token,无法连接 WebSocket');
return;
}
@@ -34,7 +36,7 @@ class WebSocketManager {
this.connected = false;
}
const url = getWsUrl(this.token);
const url = getWsUrl(this.ticket);
console.log('[WS] 正在连接:', url);
// 注册全局回调(每次调用会替换上一次的回调)
@@ -98,10 +100,22 @@ class WebSocketManager {
clearTimeout(this.reconnectTimer);
}
this.reconnectTimer = setTimeout(() => {
this.doConnect();
this.refreshTicketAndConnect();
}, delay);
}
private async refreshTicketAndConnect(): Promise<void> {
if (!this.token) return;
try {
const { ticket } = await get<{ ticket: string }>('/ws/ticket');
this.ticket = ticket;
this.doConnect();
} catch (e) {
console.error('[WS] 获取 ticket 失败:', e);
this.scheduleReconnect();
}
}
on(type: string, handler: MessageHandler): () => void {
if (!this.handlers.has(type)) {
this.handlers.set(type, new Set());