概述目标:在前后端协作中使用PKCE与`state/nonce`防护授权码拦截与重放,确保令牌签名与声明校验。适用:SPA/移动端与后端配合的登录授权;涉及OpenID Connect的身份信息获取。核心与实战生成`code_verifier`与`code_challenge`(S256):// 浏览器/前端 const codeVerifier = [...crypto.getRandomValues(new Uint8Array(64))] .map(b => ('0' + b.toString(16)).slice(-2)).join(''); const data = new TextEncoder().encode(codeVerifier); const digest = await crypto.subtle.digest('SHA-256', data); const base64url = btoa(String.fromCharCode(...new Uint8Array(digest))) .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); const codeChallenge = base64url; 授权请求(OIDC):GET https://idp.example.com/authorize? response_type=code& client_id=app-web& redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback& scope=openid%20profile%20email& state=af32c9...& nonce=9b21d1...& code_challenge=...& code_challenge_method=S256 令牌交换:curl -s -X POST https://idp.example.com/token \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=authorization_code&client_id=app-web&code=AUTH_CODE&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&code_verifier=CODE_VERIFIER' 刷新令牌:curl -s -X POST https://idp.example.com/token \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=refresh_token&client_id=app-web&refresh_token=REFRESH_TOKEN' 示例解码并校验ID Token:// 步骤: // 1) 获取 IdP 的 JWKS // 2) 使用`kid`选择公钥验证JWT签名 // 3) 校验 iss/aud/exp/nonce 与授权请求一致 curl -s https://idp.example.com/.well-known/openid-configuration | jq '.jwks_uri' curl -s https://idp.example.com/keys | jq 防重放与CSRF:// 回调校验:比较返回state与本地存储state一致;ID Token中的nonce与请求一致 验证与监控令牌与会话:校验`exp`/`iat`与时钟偏差;短期Access Token+长期Refresh Token分离存储。安全头与TLS:强制HTTPS与`Strict-Transport-Security`;禁止令牌出现在URL查询参数与日志。授权日志:监控授权失败率、刷新成功率与`invalid_grant`错误比例。常见误区使用`plain`或缺失`code_challenge_method=S256`导致安全性下降;必须使用S256。缺少`state/nonce`导致回调可被伪造;必须生成并校验两者。在前端持久化Refresh Token导致泄露风险;应存后端或受保护存储并最小权限调用。结语采用PKCE与严格令牌校验可有效提升OAuth2/OIDC安全性与一致性,适配SPA与移动端等公开客户端场景。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部
1.839900s