#python #unity/日常积累
谷歌game service v2 版本,会返回授权码: auth_code (str): Google授权码(以4/开头的字符串)
在执行相关逻辑之前,确保安装了,python库中,谷歌认证相关:
pip install google-auth requests
另外,还需要准备的材料:
![[Pasted image 20250620103522.png]]
import requests
import json
import sys
from google.oauth2 import id_token
from google.auth.transport import requests as google_requests
def exchange_auth_code(auth_code, client_id, client_secret):
"""
用授权码交换获取访问令牌和ID令牌
参数:
auth_code (str): Google授权码(以4/开头的字符串)
client_id (str): 你的Google OAuth客户端ID
client_secret (str): 你的Google OAuth客户端密钥
返回:
dict: 包含tokens和用户信息的字典
"""
token_url = "https://oauth2.googleapis.com/token"
payload = {
"code": auth_code,
"client_id": client_id,
"client_secret": client_secret,
"redirect_uri": "http://localhost",
"grant_type": "authorization_code"
}
print(f"正在交换授权码...")
try:
response = requests.post(token_url, data=payload)
if response.status_code == 200:
token_data = response.json()
print(f"令牌交换成功!")
# 获取各种令牌
access_token = token_data.get("access_token")
id_token_str = token_data.get("id_token")
refresh_token = token_data.get("refresh_token")
# 安全地打印令牌信息,避免NoneType错误
if access_token:
print(f"\n访问令牌(Access Token): {access_token[:20]}...(已截断)")
else:
print("\n访问令牌(Access Token): None")
if id_token_str:
print(f"ID令牌(ID Token): {id_token_str[:20]}...(已截断)")
else:
print("ID令牌(ID Token): None")
if refresh_token:
print(f"刷新令牌(Refresh Token): {refresh_token[:20]}...(已截断)")
else:
print("刷新令牌(Refresh Token): None")
# 保存完整令牌到文件以备后用
try:
with open("tokens.json", "w") as f:
json.dump(token_data, f, indent=2)
print(f"\n已将完整令牌保存到 tokens.json 文件")
except Exception as e:
print(f"保存令牌到文件失败: {e}")
# 验证ID令牌并获取用户信息
if id_token_str:
try:
user_info = verify_id_token(id_token_str, client_id)
return {
"tokens": token_data,
"user_info": user_info
}
except Exception as e:
print(f"ID令牌验证失败: {e}")
return {
"tokens": token_data,
"user_info": None
}
else:
print("响应中没有ID令牌")
return {
"tokens": token_data,
"user_info": None
}
else:
print(f"错误: {response.status_code}")
print(response.text)
return None
except Exception as e:
print(f"请求过程中发生错误: {e}")
return None
def verify_id_token(id_token_str, client_id):
"""
验证ID令牌并返回用户信息
参数:
id_token_str (str): 要验证的ID令牌
client_id (str): 你的Google OAuth客户端ID
返回:
dict: 用户信息字典
"""
print(f"\n正在验证ID令牌...")
try:
idinfo = id_token.verify_oauth2_token(
id_token_str,
google_requests.Request(),
client_id
)
# 验证发行者
if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']:
raise ValueError('错误的令牌发行者.')
print(f"ID令牌验证成功!")
return idinfo
except Exception as e:
print(f"ID令牌验证失败: {e}")
raise
def get_user_info_from_token(access_token):
"""
使用访问令牌获取用户信息
参数:
access_token (str): 访问令牌
返回:
dict: 用户信息字典
"""
if not access_token:
print("访问令牌为空,无法获取用户信息")
return None
print(f"\n使用访问令牌获取用户信息...")
userinfo_url = "https://openidconnect.googleapis.com/v1/userinfo"
headers = {
"Authorization": f"Bearer {access_token}"
}
try:
response = requests.get(userinfo_url, headers=headers)
if response.status_code == 200:
user_info = response.json()
print(f"获取用户信息成功!")
return user_info
else:
print(f"获取用户信息失败: {response.status_code}")
print(response.text)
return None
except Exception as e:
print(f"获取用户信息过程中发生错误: {e}")
return None
def main():
"""主函数,处理命令行参数并执行令牌交换"""
try:
if len(sys.argv) < 4:
print("用法: python exchange_code.py <授权码> <客户端ID> <客户端密钥>")
sys.exit(1)
auth_code = sys.argv[1]
client_id = sys.argv[2]
client_secret = sys.argv[3]
# 安全地截断显示参数
auth_code_display = auth_code[:10] + "...(已截断)" if len(auth_code) > 10 else auth_code
client_id_display = client_id[:15] + "...(已截断)" if len(client_id) > 15 else client_id
client_secret_display = client_secret[:5] + "...(已截断)" if len(client_secret) > 5 else client_secret
print("-" * 50)
print("Google授权码交换工具")
print("-" * 50)
print(f"授权码: {auth_code_display}")
print(f"客户端ID: {client_id_display}")
print(f"客户端密钥: {client_secret_display}")
print("-" * 50)
result = exchange_auth_code(auth_code, client_id, client_secret)
if result:
tokens = result.get("tokens", {})
user_info = result.get("user_info")
# 如果ID令牌验证失败,尝试使用访问令牌获取用户信息
if not user_info and tokens.get("access_token"):
user_info = get_user_info_from_token(tokens["access_token"])
if user_info:
print("\n----- 用户信息 -----")
print(f"用户ID: {user_info.get('sub') or user_info.get('id', 'N/A')}")
print(f"电子邮件: {user_info.get('email', 'N/A')}")
print(f"姓名: {user_info.get('name', 'N/A')}")
print(f"头像: {user_info.get('picture', 'N/A')}")
# 保存用户信息到文件
try:
with open("user_info.json", "w") as f:
json.dump(user_info, f, indent=2)
print(f"\n已将用户信息保存到 user_info.json 文件")
except Exception as e:
print(f"保存用户信息到文件失败: {e}")
else:
print("\n无法获取用户信息")
else:
print("\n令牌交换失败")
sys.exit(1)
print("\n处理完成!")
except Exception as e:
print(f"程序执行过程中发生错误: {e}")
sys.exit(1)
if __name__ == "__main__":
main()
调用方式
python .\google_token.py 4/0AUJR-x5Sbmm9wToj9ai84DdPRf-FaubSQieqnV0k2OWkVeqGg_XW08bGgyMDIxoTilbH3A 956550854222-pfjuen977e59l6hif1tj08bibh93tguu.apps.googleusercontent.com AIzaSyDLJnWUHh6o-F4e9N0fUsbGeS2sIoqyLr4
传参分别是:授权码、web客户端ID、web客户端密钥
![[Pasted image 20250620103712.png]]