SPA 公共客户端
SPA 无法保守客户端密钥,因此开放平台不会为 SPA 生成 client_secret。必须使用 Authorization Code + PKCE S256,并精确登记回调地址与 Web Origin。
function base64url(bytes: ArrayBuffer) { return btoa(String.fromCharCode(...new Uint8Array(bytes))) .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=+$/, '');}
const verifier = base64url(crypto.getRandomValues(new Uint8Array(64)));const challenge = base64url( await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier)),);sessionStorage.setItem('pkce_verifier', verifier);构造授权 URL 时同时生成高熵 state 和 nonce 并保存在 sessionStorage。回调页先校验 state,再向 token endpoint 发送:
const body = new URLSearchParams({ grant_type: 'authorization_code', client_id: CLIENT_ID, code, redirect_uri: `${location.origin}/callback`, code_verifier: sessionStorage.getItem('pkce_verifier')!,});
const response = await fetch('https://account.ylfcat.top/oauth/token', { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body,});- Access Token 尽量仅保存在内存中。
- 不要使用
localStorage长期保存 Refresh Token。 - 配置严格 CSP,限制脚本来源,避免 XSS 窃取令牌。
- 离开应用或检测到异常时调用撤销端点。