fix: P1/P2 优化 - OAuth验证 + API响应 + 缓存击穿 + Webhook关闭
P1 - OAuth auth_url origin 验证: - 添加 validateOAuthUrl() 函数验证 OAuth URL origin - 仅允许同源或可信 OAuth 提供商 - LoginPage 和 ProfileSecurityPage 调用前验证 P2 - API 响应运行时类型验证: - 添加 isApiResponse() 运行时验证函数 - parseJsonResponse 验证响应结构完整性 P2 - 缓存击穿防护 (singleflight): - AuthMiddleware.isJTIBlacklisted 使用 singleflight.Group - 防止 L1 miss 时并发请求同时打 L2 P2 - Webhook 服务优雅关闭: - WebhookService 添加 Shutdown() 方法 - 服务器关闭时等待 worker 完成 - main.go 集成 shutdown 调用
This commit is contained in:
@@ -85,7 +85,41 @@ function createTimeoutSignal(signal?: AbortSignal): { signal: AbortSignal; clean
|
||||
}
|
||||
|
||||
async function parseJsonResponse<T>(response: Response): Promise<ApiResponse<T>> {
|
||||
return response.json() as Promise<ApiResponse<T>>
|
||||
const raw = await response.json()
|
||||
|
||||
// 运行时验证响应结构
|
||||
if (!isApiResponse(raw)) {
|
||||
throw new Error('Invalid API response structure: missing required fields')
|
||||
}
|
||||
|
||||
return raw as ApiResponse<T>
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行时验证 API 响应结构
|
||||
* 防止后端返回异常格式时导致运行时错误
|
||||
*/
|
||||
function isApiResponse(obj: unknown): obj is ApiResponse<unknown> {
|
||||
if (typeof obj !== 'object' || obj === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
const r = obj as Record<string, unknown>
|
||||
|
||||
// 必须有 code 字段且为数字
|
||||
if (typeof r.code !== 'number') {
|
||||
return false
|
||||
}
|
||||
|
||||
// 必须有 message 字段且为字符串
|
||||
if (typeof r.message !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
// 如果有 data 字段,应该存在
|
||||
// (data 可以是 undefined/null/任何类型,但我们允许这些值)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
async function refreshAccessToken(): Promise<TokenBundle> {
|
||||
|
||||
Reference in New Issue
Block a user