带加密参数请求Google Analytics API获取AccessToken报无效授权类型错误
问题描述
尝试通过Google Analytics API的Refresh Token生成AccessToken时,使用Python库加密请求参数后返回错误:
{'error': 'unsupported_grant_type', 'error_description':'Invalid grant_type: '}
不加密参数时,请求可正常执行并成功获取AccessToken,需要排查问题并提供解决方案。
原代码
import os import requests import json import base64 import random from Crypto import Random from Crypto.Cipher import AES from Crypto.Random import get_random_bytes from Crypto.Util.padding import pad,unpad import secrets key= os.urandom(16) iv = Random.new().read(AES.block_size) def encrypt_data(key, data): BS = AES.block_size pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode() cipher = AES.new(key, AES.MODE_CBC, iv) encrypted_data = base64.b64encode(cipher.encrypt(pad(data))) return encrypted_data base_url = "https://accounts.google.com" client_Id = "XXXXX" client_secret = "YYYYY" grant_type = "refresh_token" refresh_token = "ZZZZZZ" access_type="offline" data = { "grant_type":grant_type, "client_id":client_Id, "client_secret":client_secret, "refresh_token":refresh_token, "access_type":access_type } encode_string = json.dumps(data).encode("utf-8") response = requests.post(base_url+"/o/oauth2/token?", params=encrypt_data(key,encode_string)).json() print(response.content)
问题排查
- 接口不支持自定义参数加密:Google OAuth2的
/o/oauth2/token端点仅接受明文的application/x-www-form-urlencoded或JSON格式参数,无法解密你自定义加密后的内容,导致服务器无法识别grant_type等必填参数,直接返回错误。 - 参数传递位置错误:原代码将加密后的参数放到了URL查询参数(
params)中,即使不加密,正确的做法也应该是把参数放在请求体(data参数)里,而非URL参数。
解决方案
核心结论
Google OAuth2的token接口不支持自定义加密参数,HTTPS协议本身已经对整个请求传输过程进行了加密,足够保证参数传输安全。如果要保护敏感信息(如client_secret),建议通过环境变量存储,避免硬编码到代码中。
修正后的代码
import os import requests # 推荐从环境变量读取敏感信息,避免硬编码 client_Id = os.getenv("GOOGLE_CLIENT_ID", "XXXXX") client_secret = os.getenv("GOOGLE_CLIENT_SECRET", "YYYYY") refresh_token = os.getenv("GOOGLE_REFRESH_TOKEN", "ZZZZZZ") base_url = "https://accounts.google.com/o/oauth2/token" data = { "grant_type": "refresh_token", "client_id": client_Id, "client_secret": client_secret, "refresh_token": refresh_token # access_type仅在授权码流程获取授权码时需要,刷新token阶段无需传递 } # 发送表单格式的请求体,这是Google OAuth2接口推荐的参数格式 response = requests.post(base_url, data=data) response.raise_for_status() # 主动捕获HTTP请求错误 print(response.json())
额外说明
access_type参数仅在授权码流程获取授权码时需要,刷新token阶段不需要传递,可直接移除。- 使用
requests.post的data参数传递表单数据,比JSON格式兼容性更好,符合Google官方推荐的请求方式。
内容的提问来源于stack exchange,提问作者sac
相关产品推荐
相关产品推荐

