0

我正在使用带有使用服务帐户生成的 jwt 的 http post 报告设备的状态。下面是 jwt 的有效载荷

{
   "iss": "<service-account-email>",
   "scope": "https://www.googleapis.com/auth/homegraph",
   "aud": "https://accounts.google.com/o/oauth2/token",
   "iat": <current-time>,
   "exp": <current-time-plus-one-hour>
 }

在此之后,我使用 python 库 google.auth.crypt.RSASigner.from_service_account_file(path) 使用我的服务帐户的私钥签署 jwt 并生成 jwt 令牌。我进一步使用此令牌从https://accounts.google.com/o/oauth/token获取访问令牌,这也是成功的。获得访问令牌后,我向 https://homegraph.googleapis.com/v1/devices:reportStateAndNotification?key=api_key发出发布请求

带标题

{"Authorization": "Bearer <token>", "X-GFE-SSL": "yes", "Content-Type": "application/json"}

和json数据

{ "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf", "agent_user_id": "1234", "payload": { "devices": { "states": { "1458765": { "on": true }, "4578964": { "on": true, "isLocked": true } } } } }

但这给了我

{'error': {'code': 403, 'message': 'The request is missing a valid API key.', 'status': 'PERMISSION_DENIED'}}

我按照 https://developers.google.com/actions/smarthome/report-state 中的步骤操作我做错了什么吗?还是我错过了任何步骤?

更新:我将 api 密钥添加到 uri 现在它给了我另一个错误响应

{'error': {'code': 403, 'message': 'The caller does not have permission', 'status': 'PERMISSION_DENIED'}}

我该如何解决这个问题?

4

1 回答 1

0

为了向主图表报告状态,您必须:

  • 为您的 SmartHomeApp 项目创建令牌创建一个服务帐户:
  • 转到API 和服务=> 单击凭据 转到“API 和服务”=> 单击“凭据”
  • 单击创建凭据=> 单击服务帐户密钥 单击“创建凭据”=> 单击“服务帐户密钥”
  • 填写您的数据创建一个新的新服务帐户=> 选择角色服务帐户 > 服务帐户令牌创建者 填写您的数据,创建一个新的“新服务帐户”=> 选择角色“服务帐户 > 服务帐户令牌创建者”
  • JSON使用您的密钥和证书下载文件
  • 获取有效的签名 JWT 令牌

    credentials = service_account.Credentials.from_service_account_file(service_account_file, scopes="https://www.googleapis.com/auth/homegraph")
    
    now = int(time.time())
    expires = now + 3600  # One hour in seconds
    
    payload = {
        'iat': now,
        'exp': expires,
        'aud': "https://accounts.google.com/o/oauth2/token",
        'scope': SCOPE,
        'iss': credentials.service_account_email
    }
    
    signed_jwt = google.auth.jwt.encode(credentials.signer, payload)
    
  • 获取有效的访问令牌

    headers = {"Authorization": "Bearer {}".format(signed_jwt.decode("utf-8")), "Content-Type": "application/x-www-form-urlencoded"}
    data = {"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": signed_jwt}
    
    access_token = requests.post("https://accounts.google.com/o/oauth2/token", data=data, headers=headers).get("access_token")
    
  • 发送报告的状态:

    headers = {"Authorization": "Bearer {}".format(access_token), "X-GFE-SSL": "yes"}
    data = {"requestId": request_id, "agent_user_id": agent_user_id, "payload": {"devices": {"states": states}}}
    
    requests.post("https://homegraph.googleapis.com/v1/devices:reportStateAndNotification", data=json.dumps(data), headers=headers)
    

注意:为了工作,这些代码片段需要to 、import google.auth.jwtfrom和from google.oauth2 import service_accountpackages 。import requestsgoogle-authgoogle-auth-httplib2requests

于 2018-07-25T13:26:10.443 回答