As a supplement, this is the complete code example for obtaining the token. Confidential information has been hidden.
import requests
import jwt
from datetime import datetime, timedelta, timezone
from cryptography.hazmat.primitives import serialization
# 其他配置示例(注释掉的备用配置)
KEY_ID = "Z7S8S2xxxx"
TEAM_ID = "6VNZUKxxxx"
CLIENT_ID = "com.game.friends.ios.toptop.xxxx"
P8_KEY_FILE = "AuthKey_Z7S8S2xxxx.p8"
def generate_client_secret():
"""使用p8密钥生成JWT格式的client_secret"""
try:
# 从文件读取 p8 密钥内容
# with open(P8_KEY_FILE, 'r') as f:
# p8_key_content = f.read()
p8_key_content = serialization.load_pem_private_key(
open(P8_KEY_FILE, 'rb').read(),
password=None
)
print(f"从文件读取密钥: {p8_key_content}")
# 计算时间戳
now = datetime.now(timezone.utc) # 替代弃用的 utcnow()
issued_at = int(now.timestamp())
expiration = int((now + timedelta(days=180)).timestamp())
# 创建JWT头部
headers = {
"alg": "ES256",
"kid": KEY_ID,
}
# 创建JWT有效载荷
payload = {
"iss": TEAM_ID,
"iat": issued_at,
"exp": expiration,
"aud": "https://appleid.apple.com",
"sub": CLIENT_ID
}
print("生成的 payload:", payload)
# 生成签名的JWT作为client_secret
client_secret = jwt.encode(
payload,
p8_key_content,
algorithm="ES256",
headers=headers
)
return client_secret
except FileNotFoundError:
print(f"密钥文件未找到: {P8_KEY_FILE}")
return None
except Exception as e:
print(f"生成client_secret失败: {str(e)}")
return None
def get_apple_token():
"""获取Apple的访问令牌"""
# 生成JWT格式的client_secret
client_secret = generate_client_secret()
print("生成的 client_secret:", client_secret)
if not client_secret:
print("无法生成client_secret,退出")
return None
# 设置请求参数
url = "https://appleid.apple.com/auth/token"
headers = {"Content-Type": "application/x-www-form-urlencoded"}
data = {
"grant_type": "client_credentials",
"scope": "user.migration",
"client_id": CLIENT_ID,
"client_secret": client_secret,
"redirect_uri": "https://example.com/auth/callback"
}
try:
# 发送请求
response = requests.post(url, headers=headers, data=data)
response.raise_for_status() # 检查HTTP错误
# 返回JSON响应
return response.json()
except requests.exceptions.HTTPError as err:
# 处理HTTP错误
print(f"HTTP错误 ({err.response.status_code}):")
if err.response.text:
print(err.response.text)
return None
except Exception as e:
# 处理其他错误
print(f"请求失败: {str(e)}")
return None
# 主程序入口
if __name__ == "__main__":
# 获取访问令牌
token_response = get_apple_token()
if token_response:
print("\n成功获取Apple访问令牌:")
print(f"访问令牌: {token_response.get('access_token')}")
print(f"令牌类型: {token_response.get('token_type')}")
print(f"有效期: {token_response.get('expires_in')}秒")
else:
print("\n无法获取访问令牌,请检查错误信息")