背景与价值预签名URL若无治理易被滥用。统一过期、范围与来源校验,可显著降低风险并提升可审计能力。统一规范有效期:`expires` 不得超过业务上限(如15分钟)。资源范围:仅允许指定前缀下资源访问,拒绝任意路径。IP白名单:仅允许批准IP来源访问。核心实现签名生成与校验function enc(s: string): Uint8Array { return new TextEncoder().encode(s) } async function importHmac(secret: ArrayBuffer): Promise<CryptoKey> { return crypto.subtle.importKey('raw', secret, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']) } async function hmac(key: CryptoKey, data: string): Promise<string> { const raw = await crypto.subtle.sign('HMAC', key, enc(data)) const u = new Uint8Array(raw) let s = '' for (let i=0;i<u.length;i++) s += String.fromCharCode(u[i]) return btoa(s).replace(/\+/g,'-').replace(/\//g,'_').replace(/=+$/,'') } type Token = { path: string; expires: number; sig: string } async function signToken(path: string, expires: number, key: CryptoKey): Promise<Token> { const payload = path + '|' + String(expires) const sig = await hmac(key, payload) return { path, expires, sig } } function withinPrefix(path: string, prefix: string): boolean { return path.startsWith(prefix) } function ipAllowed(ip: string, allow: Set<string>): boolean { return allow.has(ip) } async function verifyToken(t: Token, key: CryptoKey, prefix: string, ip: string, allow: Set<string>, maxExpMs: number): Promise<boolean> { if (!withinPrefix(t.path, prefix)) return false if (!ipAllowed(ip, allow)) return false const now = Date.now() if (t.expires - now > maxExpMs || now > t.expires) return false const expect = await hmac(key, t.path + '|' + String(t.expires)) return expect === t.sig } 落地建议为预签名URL设置较短有效期,拒绝超上限;资源路径限定前缀并记录审计。配置来源IP白名单并在边缘进行阻断与校验,减少外泄面。将签名策略与网关协同,统一过期与来源策略并清理失效令牌。验证清单`expires` 是否在上限内且未过期。`path` 是否命中前缀范围,来源IP是否在白名单内。签名是否与负载一致并通过校验。

发表评论 取消回复