【问题标题】:401 Error - Google API with service account401 错误 - 带有服务帐户的 Google API
【发布时间】:2021-03-18 13:49:20
【问题描述】:

用户好。

我正在尝试通过 Google 服务帐户写入 Google 表格文档。该帐户对文档具有写入权限,所以这不是问题。

我使用服务帐户的原因是为了避免必须不断刷新访问令牌。我认为这就是问题所在。因为这是来自 API 的响应:

{
  "error": {
    "code": 401,
    "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. 
See https://developers.google.com/identity/sign-in/web/devconsole-project.",
    "status": "UNAUTHENTICATED"
  }
}

当我尝试向电子表格发送 put 请求以编辑数据时会发生这种情况。我之前将服务帐户连接到工作表 API,从那里获取凭据并在请求中使用它们。

如果有人知道错误可能在哪里,我将非常感谢。

这是触发错误的 Python 代码:

        iat = time.time()
        exp = iat + 3600
        payload = {'iss': <SERVICE ACCOUNT EMAIL>,
                   'sub': <SERVICE ACCOUNT EMAIL>,
                   'aud': f'https://sheets.googleapis.com/v4/spreadsheets/<SHEETID>/values/Sheet1!A2:B5',
                   'iat': iat,
                   'exp': exp}
        additional_headers = {'kid': <PRIVATE KEY ID>}
        signed_jwt = jwt.encode(payload, key=<PRIVATE KEY>, 
                                headers=additional_headers, algorithm='RS256')

        headers = {'authorization': f'Bearer {signed_jwt}'}
        params = {'range': f'Sheet1!A2B5',
                  'majorDimension':'ROWS',
                  'values':[
                      <LISTS OF ENTRIES>
                  ]}
        spreadsheetId = <SHEETID>
        resp = requests.put(url=f'https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/
                                  values/Sheet1!A2:B5?valueInputOption=USER_ENTERED',
                                  data = params, headers = headers)

对于任何感兴趣的人,我都在遵循这些指南:

如何使用服务帐号进行身份验证:https://developers.google.com/identity/protocols/oauth2/service-account#python_1

如何发出正确的 put 请求:https://developers.google.com/sheets/api/samples/writing

如何为 jwt 编码的凭据获取正确的端点:https://developers.google.com/sheets/api/reference/rest

【问题讨论】:

    标签: python-3.x google-sheets google-api python-requests


    【解决方案1】:

    预期的 OAuth 2 访问令牌、登录 cookie 或其他有效的身份验证凭据。

    用于使用服务帐户访问 API 的代码与用于 Oauth2 的代码不同。您正在使用的代码似乎正在尝试使用 Oauth2 进行身份验证。

    你应该使用这样的东西。

    credentials = ServiceAccountCredentials.from_json_keyfile_name(
      KEY_FILE_LOCATION, SCOPES)
    
    service = build('calendar', 'v3', credentials=credentials)
    

    参考:

    【讨论】:

    • 谢谢!虽然我使用的是 python requests 模块,而不是 API 的 python 包装器。请求也可以这样吗?
    • 有什么特别的原因不想使用 Python 官方库吗?要通过requests 拨打电话,您应该关注this
    • 谢谢,这正是我所需要的。
    猜你喜欢
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-28
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多