使用Google服务账号生成JWT发起POST请求时遭遇401错误求助
解决Google服务账号JWT认证401错误的问题
你在使用Google服务账号生成JWT调用Actions API时碰到了401未授权错误,我帮你梳理几个关键问题和修复方案:
核心问题分析
你的代码里有几个容易触发401的问题点:
- 受众(aud)字段填错了:你把OAuth的权限范围(scope)放到了
aud字段里,但JWT的aud应该是目标API的受众标识,不是权限范围。 - 没声明权限范围:JWT的payload里缺少
scope字段,Google服务端没法确认你请求的权限是什么。 - 请求头缺了Content-Type:你发送的是JSON数据,但没告诉服务器,导致服务器可能解析不了请求体,间接引发认证失败。
修正后的代码
生成JWT的函数调整
import time import json import google.auth.crypt import google.auth.jwt import requests def generate_jwt(): # 加载服务账号文件 with open("service_account_file.json") as json_file: service_account_info = json.load(json_file) signer = google.auth.crypt.RSASigner.from_service_account_file("service_account_file.json") now = int(time.time()) expires = now + 3600 # 1小时有效期 payload = { 'iat': now, 'exp': expires, # 修正aud字段:改为Actions API的受众标识 'aud': 'https://actions.googleapis.com/', # 从服务账号文件读取client_email,避免硬编码出错 'iss': service_account_info['client_email'], 'sub': service_account_info['client_email'], # 添加scope字段,明确声明需要的权限范围 'scope': 'https://www.googleapis.com/auth/actions.fulfillment.conversation' } jwt = google.auth.jwt.encode(signer, payload) return jwt
请求部分调整
# 准备请求头,必须包含Content-Type headers = { 'Authorization': 'Bearer {}'.format(generate_jwt()), 'Content-Type': 'application/json' } url = 'https://actions.googleapis.com/v2/conversations:send' # 用requests的json参数自动处理序列化,比手动json.dumps更可靠 response = requests.post(url, json=notif, headers=headers) print(response.status_code) print(response.text)
额外要检查的地方
- 确认你的服务账号已经被授予了
actions.fulfillment.conversation相关的权限,而且Google Cloud控制台里已经启用了Actions API。 - 检查服务账号文件的路径是否正确,文件内容有没有损坏。
- 如果还是报错,可以打印出生成的JWT,用JWT解码工具检查payload里的字段是否都正确。
内容的提问来源于stack exchange,提问作者akhil reddy
相关产品推荐
相关产品推荐

