PKCE 是什么
一句话总结
PKCE(读作 “pixy”)是 Authorization Code Flow 的安全补丁——在临时授权码上面又加了一个”暗号验证”,即使攻击者截获了授权码,没有暗号也换不到真正的令牌。
🤔 为什么会有它 / 解决了什么问题
Authorization Code Flow 有一个安全漏洞:如果恶意应用注册了相同的 redirect_uri,或者攻击者监听了浏览器,就能截获 URL 里的 code,然后自己拿它去换令牌,冒充你登录。
PKCE 堵的就是这个洞。它加了一个只有原始发起方才知道的随机数——攻击者截获了 code 也没用,因为没有这个随机数。
🔍 具体原理 / 运作逻辑
PKCE 在标准 Auth Code Flow 上加了两步:
第一步:生成随机数(在用户浏览器里)
code_verifier = 一段随机字符串(比如 128 位 Base64URL)
code_challenge = SHA256(code_verifier) → Base64URL 编码
第二步:启动授权请求(带着 challenge 去 IDP)
GET /authorize?code_challenge=xxx&code_challenge_method=S256
IDP 记住了这个 challenge
第三步:用授权码 + verifier 换令牌
POST /token?code=xxx&code_verifier=原始随机数
IDP 计算 SHA256(code_verifier) 对比之前存的 challenge
匹配 → 放行,不匹配 → 拒绝
更硬核的技术细节(点击展开)
- PKCE 有两种模式:
S256(SHA256 哈希,推荐)和plain(明文,不推荐)- Frappe 完整支持 PKCE S256,在
frappe/oauth.py里实现- PKCE 原本为移动 App 设计(没有后端),但现在 OAuth 2.1 草案强制所有场景都用 PKCE
- code_verifier 要求 43-128 字符,Grafana/n8n 等 OIDC 库会自动生成,不需要手动处理
🧭 什么情况下会用到 / 什么场景会遇到它
- 任何”用 Google/GitHub 登录”的现代应用背后都有 PKCE
- 配置 OIDC 客户端时,如果看到
use_pkce: true或code_challenge_method: S256,就是这个 - 我们配 Grafana/Outline 时默认就会启用 PKCE
🔗 关联 / 经常一起出现的概念
- Authorization Code Flow:PKCE 是它的安全增强版
- OIDC:OIDC 推荐配合 PKCE 使用
- OAuth 2.0:PKCE 是 OAuth 2.0 的扩展(RFC 7636)
📎 记忆锚点
PKCE = 快递取件码。快递员(攻击者)看到你家门口有个包裹通知(授权码),但他不知道你的取件码(code_verifier),所以取不走包裹。
📝 更新日志
| 日期 | 改动 | 原因 |
|---|---|---|
| 2026-07-09 | 首次创建 | Frappe SSO/OIDC 集成准备 |