代码交换证明密钥(Proof Key for Code Exchange,简称PKCE)
代码交换证明密钥(Proof Key for Code Exchange,简称PKCE)是一种用于增强OAuth 2.0授权码流程安全性的扩展机制。PKCE主要用于公共客户端(如原生应用和单页应用),这些客户端无法安全地存储客户端密钥(Client Secret)。PKCE通过引入一个额外的“证明密钥”来防止授权码被拦截和滥用。
PKCE的工作原理
生成Code Verifier: 客户端生成一个随机的、足够长的字符串,称为
code_verifier
。这个字符串是唯一的,并且只在当前授权请求中使用。生成Code Challenge: 客户端对
code_verifier
进行哈希处理(通常使用SHA-256算法),并将结果进行Base64 URL编码,得到code_challenge
。发起授权请求: 客户端将
code_challenge
和code_challenge_method
(例如“S256”表示使用SHA-256算法)一起发送到授权服务器的授权端点(/authorize)。用户认证和授权: 用户在授权服务器上进行认证并授权,授权服务器生成授权码并将其返回给客户端。
交换授权码: 客户端将授权码和之前生成的
code_verifier
一起发送到授权服务器的令牌端点(/token)。验证Code Verifier: 授权服务器使用收到的
code_verifier
和之前存储的code_challenge
进行验证。如果验证通过,授权服务器返回访问令牌和刷新令牌。
PKCE的安全性
PKCE通过引入code_verifier
和code_challenge
,确保只有发起授权请求的客户端才能成功交换授权码。这有效地防止了授权码拦截攻击,因为即使攻击者截获了授权码,也无法在没有code_verifier
的情况下成功交换令牌。
示例代码
以下是一个使用PKCE的伪代码示例:
import hashlib
import base64
import os
# 生成code_verifier
code_verifier = base64.urlsafe_b64encode(os.urandom(32)).decode('utf-8').rstrip('=')
# 生成code_challenge
code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode('utf-8')).digest()).decode('utf-8').rstrip('=')
# 发起授权请求
authorization_url = f"https://authorization-server.com/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&code_challenge={code_challenge}&code_challenge_method=S256"
print("请访问以下URL进行授权:", authorization_url)
# 用户完成授权后,使用code_verifier交换授权码
authorization_code = input("请输入授权码: ")
token_response = requests.post("https://authorization-server.com/token", data={
'grant_type': 'authorization_code',
'code': authorization_code,
'redirect_uri': 'YOUR_REDIRECT_URI',
'client_id': 'YOUR_CLIENT_ID',
'code_verifier': code_verifier
})
print("访问令牌:", token_response.json().get('access_token'))
参考资料
最后更新于