File size: 4,168 Bytes
69b897d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
/**
* 客户端验证器
* 用于验证请求是否来自特定的客户端
*/
const logger = require('../utils/logger')
const { CLIENT_DEFINITIONS, getAllClientDefinitions } = require('./clientDefinitions')
const ClaudeCodeValidator = require('./clients/claudeCodeValidator')
const GeminiCliValidator = require('./clients/geminiCliValidator')
const CodexCliValidator = require('./clients/codexCliValidator')
const DroidCliValidator = require('./clients/droidCliValidator')
/**
* 客户端验证器类
*/
class ClientValidator {
/**
* 获取客户端验证器
* @param {string} clientId - 客户端ID
* @returns {Object|null} 验证器实例
*/
static getValidator(clientId) {
switch (clientId) {
case 'claude_code':
return ClaudeCodeValidator
case 'gemini_cli':
return GeminiCliValidator
case 'codex_cli':
return CodexCliValidator
case 'droid_cli':
return DroidCliValidator
default:
logger.warn(`Unknown client ID: ${clientId}`)
return null
}
}
/**
* 获取所有支持的客户端ID列表
* @returns {Array<string>} 客户端ID列表
*/
static getSupportedClients() {
return ['claude_code', 'gemini_cli', 'codex_cli', 'droid_cli']
}
/**
* 验证单个客户端
* @param {string} clientId - 客户端ID
* @param {Object} req - Express请求对象
* @returns {boolean} 验证结果
*/
static validateClient(clientId, req) {
const validator = this.getValidator(clientId)
if (!validator) {
logger.warn(`No validator found for client: ${clientId}`)
return false
}
try {
return validator.validate(req)
} catch (error) {
logger.error(`Error validating client ${clientId}:`, error)
return false
}
}
/**
* 验证请求是否来自允许的客户端列表中的任一客户端
* @param {Array<string>} allowedClients - 允许的客户端ID列表
* @param {Object} req - Express请求对象
* @returns {Object} 验证结果对象
*/
static validateRequest(allowedClients, req) {
const userAgent = req.headers['user-agent'] || ''
const clientIP = req.ip || req.connection?.remoteAddress || 'unknown'
// 记录验证开始
logger.api(`🔍 Starting client validation for User-Agent: "${userAgent}"`)
logger.api(` Allowed clients: ${allowedClients.join(', ')}`)
logger.api(` Request from IP: ${clientIP}`)
// 遍历所有允许的客户端进行验证
for (const clientId of allowedClients) {
const validator = this.getValidator(clientId)
if (!validator) {
logger.warn(`Skipping unknown client ID: ${clientId}`)
continue
}
logger.debug(`Checking against ${validator.getName()}...`)
try {
if (validator.validate(req)) {
// 验证成功
logger.api(`✅ Client validated: ${validator.getName()} (${clientId})`)
logger.api(` Matched User-Agent: "${userAgent}"`)
return {
allowed: true,
matchedClient: clientId,
clientName: validator.getName(),
clientInfo: Object.values(CLIENT_DEFINITIONS).find((def) => def.id === clientId)
}
}
} catch (error) {
logger.error(`Error during validation for ${clientId}:`, error)
continue
}
}
// 没有匹配的客户端
logger.api(`❌ No matching client found for User-Agent: "${userAgent}"`)
return {
allowed: false,
matchedClient: null,
reason: 'No matching client found'
}
}
/**
* 获取客户端信息
* @param {string} clientId - 客户端ID
* @returns {Object} 客户端信息
*/
static getClientInfo(clientId) {
const validator = this.getValidator(clientId)
if (!validator) {
return null
}
return validator.getInfo()
}
/**
* 获取所有可用的客户端信息
* @returns {Array<Object>} 客户端信息数组
*/
static getAvailableClients() {
// 直接从 CLIENT_DEFINITIONS 返回所有客户端信息
return getAllClientDefinitions()
}
}
module.exports = ClientValidator
|