【问题标题】:App Engine OAuth2.0 authorized cron job to analyze Google SheetApp Engine OAuth2.0 授权 cron 作业分析 Google Sheet
【发布时间】:2017-02-16 12:08:29
【问题描述】:

我正在创建一个 Google App Engine 项目,它将每 5 分钟自动触发一个函数来分析 Google 表格。

OAuth 授权

待分析工作表是 G Suite 工作表,仅对公司成员公开。所以我需要 OAuth2 来授权访问。我该怎么做?

我想我需要一个服务帐户客户端 ID,因为它会在服务器中自动运行,所以不能有 OAuth2 流程,对吧?如果函数在服务器中运行,谁会点击按钮?

我需要一些指示。

谢谢

https://developers.google.com/identity/protocols/OAuth2ServiceAccount

【问题讨论】:

    标签: python google-app-engine oauth-2.0


    【解决方案1】:

    是的,它是一种 OAuth2 流程,但不涉及手动用户操作 - 操作由服务器根据预先配置的信息自动执行。从您提到的文档中:

    Google OAuth 2.0 系统支持服务器到服务器的交互 例如 Web 应用程序和 Google 服务之间的那些。为了这 场景你需要一个服务账户,这是一个属于 到您的应用程序而不是单个最终用户。您的 应用程序代表服务帐户调用 Google API,因此 用户不直接参与。这种情况有时被称为 “双腿 OAuth”或“2LO”。 (相关术语“三足 OAuth” 指您的应用程序调用 Google API 的场景 代表最终用户,有时需要用户同意。)

    基本上你需要:

    要将域范围的权限委托给服务帐户,请首先启用 服务中现有服务帐户的域范围委派 帐户页面或创建具有域范围的新服务帐户 启用委派。

    然后,G Suite 域的管理员必须完成 以下步骤:

    1. 转到您 G Suite 域的管理控制台。
    2. 从控件列表中选择安全。如果您没有看到列出的安全性,请从底部的灰色栏中选择更多控件 ,然后从控件列表中选择安全性。如果你 看不到控件,请确保您以管理员身份登录 域。
    3. 从选项列表中选择显示更多,然后选择高级设置。
    4. 在身份验证部分选择管理 API 客户端访问。
    5. 在“客户名称”字段中输入服务帐户的客户 ID。您可以在 Service accounts page 中找到您的服务帐号的客户端 ID。
    6. 在一个或多个 API 范围字段中,输入应授予您的应用程序访问权限的范围列表。例如,如果您的 应用程序需要对 Google Drive API 和 谷歌日历 API,输入:https://www.googleapis.com/auth/drivehttps://www.googleapis.com/auth/calendar
    7. 单击授权。

    您的应用程序现在有权以用户身份进行 API 调用 您的域(以“模拟”用户)。当你准备制作 授权的 API 调用,您指定要模拟的用户。

    【讨论】:

    • 非常感谢,但我想知道是否有办法避免涉及 G Suite 管理员...实际上我实际上无权访问它。
    • 我不认为这是可能的,因为在 G Suite 中执行文档访问控制。
    • 我终于在没有全域解决方案的情况下做到了,我还在摸不着头脑,但它确实有效。将发布解决方案。感谢您的帮助。
    【解决方案2】:

    最后我这样解决了:

    • 设置一个新的 App Engine 服务帐户(我不知道是否真的需要一个“新”服务帐户)
    • 记下新的服务帐户电子邮件
    • 与该服务帐户邮件共享工作表(如果没有此步骤,我尚未对其进行测试)
    • 以 JSON 格式下载其服务机密。
    • 使用此代码(受 (1) 和 (2) 启发)

      class analysisHandler(Handler):
          def get(self):
      
              credentials = ServiceAccountCredentials.from_json_keyfile_name('service-secrets.json',
                                 ["https://www.googleapis.com/auth/spreadsheets"])
      
              http = httplib2.Http()
      
               #if credentials are still valid
              if not credentials.invalid:
                  logging.info("Valid credentials, entering main function")
                  http = credentials.authorize(http)
                  main(http)
              else:
                  credentials.refresh(http)
                  main(http)
      

    然后在main()中:

    sheetService = discovery.build('sheets', 'v4', http=authorized_http)
    logging.info("Reading Google Sheet")
    result = sheetService.spreadsheets().values().get(spreadsheetId=spreadsheet_id, range=range_name).execute(http=authorized_http)
    
    urlfetch.set_default_fetch_deadline(45)
    logging.info("Printing in Google Sheet")
    sheetService.spreadsheets().values().append(spreadsheetId=spreadsheet_id, range="Log", body=body, valueInputOption="USER_ENTERED").execute(http=authorized_http)
    

    authorized_http 参数是之前使用 credentials.authorize() 构建的参数

    我认为这可以改进。

    (1)How to use "Service account" authorization (rather than user based access refresh tokens)

    (2)Creating and sharing Google Sheet spreadsheets using Python

    【讨论】:

    • 但是您确实意识到,通过这种方法,电子表格不再“只对公司成员公开”(因为它与外部实体共享),对吧?
    • 哦,是的,使用服务帐户,感谢您的指出。这会奏效。
    猜你喜欢
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    • 2017-11-30
    • 2019-04-14
    • 1970-01-01
    • 2015-11-19
    • 2023-03-14
    • 2018-09-23
    相关资源
    最近更新 更多