import { twilioConfig } from '../config/twilio'; export interface TokenRequest { identity: string; roomName: string; apiKey?: string; apiSecret?: string; } export interface TokenResponse { token: string; identity: string; roomName: string; } // 模拟Token生成服务 // 在实际生产环境中,这应该是一个后端API服务 export class TokenService { // 生成访问令牌 async generateAccessToken(request: TokenRequest): Promise { try { // 在实际应用中,这里应该调用后端API // 这里我们创建一个模拟的token const mockToken = this.generateMockToken(request.identity, request.roomName); return { token: mockToken, identity: request.identity, roomName: request.roomName, }; } catch (error) { console.error('Error generating access token:', error); throw new Error('Failed to generate access token'); } } // 生成模拟Token(仅用于开发测试) private generateMockToken(identity: string, roomName: string): string { // 这是一个简化的JWT模拟 // 实际应用中应该使用Twilio SDK在后端生成真实的token const header = { typ: 'JWT', alg: 'HS256', cty: 'twilio-fpa;v=1' }; const payload = { iss: twilioConfig.apiKey, sub: twilioConfig.accountSid, nbf: Math.floor(Date.now() / 1000), exp: Math.floor(Date.now() / 1000) + 3600, // 1小时有效期 jti: `${twilioConfig.apiKey}-${Date.now()}`, grants: { identity: identity, video: { room: roomName } } }; // 在实际应用中,这里应该用正确的签名算法 const encodedHeader = btoa(JSON.stringify(header)); const encodedPayload = btoa(JSON.stringify(payload)); const signature = btoa(`${twilioConfig.apiSecret}-signature`); return `${encodedHeader}.${encodedPayload}.${signature}`; } // 验证Token(模拟) validateToken(token: string): boolean { try { const parts = token.split('.'); if (parts.length !== 3) return false; const payload = JSON.parse(atob(parts[1])); const now = Math.floor(Date.now() / 1000); return payload.exp > now; } catch { return false; } } // 解析Token信息 parseToken(token: string): { identity: string; roomName: string } | null { try { const parts = token.split('.'); if (parts.length !== 3) return null; const payload = JSON.parse(atob(parts[1])); return { identity: payload.grants?.identity || '', roomName: payload.grants?.video?.room || '', }; } catch { return null; } } } export const tokenService = new TokenService(); // Express.js API端点示例(如果需要真实的后端服务) export const createTokenEndpoint = () => { return async (req: any, res: any) => { try { const { identity, roomName } = req.body; if (!identity || !roomName) { return res.status(400).json({ error: 'Identity and roomName are required' }); } const tokenResponse = await tokenService.generateAccessToken({ identity, roomName, }); res.json(tokenResponse); } catch (error) { console.error('Token generation error:', error); res.status(500).json({ error: 'Failed to generate token' }); } }; };