【问题标题】:unable to connect to localhost after allowing permissions for the google app允许谷歌应用程序权限后无法连接到本地主机
【发布时间】:2019-12-18 10:29:13
【问题描述】:

我想实现一个允许我访问 Google Drive 的简单应用程序。我关注python quickstart。我在 Docker 中运行应用程序。

但是,当我运行脚本时,它会显示Please visit this URL to authorize this application:。如果我通过它要求我选择帐户的 URL,显示关于它不是经过验证的应用程序的警告(我忽略它并转到我的应用程序页面),要求访问谷歌驱动器和元数据(我允许它),然后它将我重定向到 http://localhost:46159/?state=f.. 并显示 unable to connect 页面。端口可能不同。

有什么问题?有没有办法阻止在 Docker 中运行的应用请求验证?

【问题讨论】:

  • 1 您将始终要求用户访问他们的数据。 2 在您完成验证过程之前,您的应用程序将向用户显示为未验证。这些事情都与您将其托管在 docker 上这一事实无关
  • 所以没有机会拥有一个可以访问我的驱动器并列出文件而无需每次都允许访问的烦人过程的应用程序?
  • @DaImTo 和关于 docker。身份验证通过某些端口将我重定向到本地主机。但我只运行 docker 应用程序,所以它会将我重定向到 docker。
  • docker 容器应设置为 web url。您需要在代码中将重定向 URI 设置为该值。你不能重定向到 docker 容器上的本地主机,你需要有一个谷歌可以访问的外部地址

标签: python docker google-api google-drive-api google-oauth


【解决方案1】:

为了避免“要求验证”过程,您可以改为通过服务帐户使用授权。

为此,首先我们必须创建服务帐户:

  1. 导航到您的 GCP 项目。
  2. 转到Credentials
  3. 单击创建凭据>服务帐户密钥
  4. 设置服务帐户名称、ID 和角色(如果适用)。将密钥类型保留为 JSON。
  5. 点击Create。将下载一个 JSON 文件,其中包含新创建的服务帐户的凭据。

现在,将文件复制到保存项目的文件夹并使用以下修改后的代码(基于您使用的快速入门示例):

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2 import service_account

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly']
SERVICE_ACCOUNT_FILE = '/path/to/service.json'

def main():
    """Shows basic usage of the Drive v3 API.
    Prints the names and ids of the first 10 files the user has access to.
    """
   creds = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    service = build('drive', 'v3', credentials=creds)

    # Call the Drive v3 API
    results = service.files().list(
        pageSize=10, fields="nextPageToken, files(id, name)").execute()
    items = results.get('files', [])

    if not items:
        print('No files found.')
    else:
        print('Files:')
        for item in items:
            print(u'{0} ({1})'.format(item['name'], item['id']))

if __name__ == '__main__':
    main()

请注意,服务帐户的行为类似于普通帐户(它们有自己的文件、权限等)。如果您希望服务帐户像您域的现有用户一样工作,您可以使用Domain-wide delegation 来实现。

参考

【讨论】:

  • 所以基本上除了创建service account之外,我必须使用域范围的委派来提供对我的谷歌驱动器文件夹的访问权限
  • @lapots 是正确的。或者,您可以与服务帐户共享文件夹(您可以像与域中的任何其他用户共享它一样 - 通过指定帐户电子邮件)并将文件上传到它。这种替代方案可能会更安全,因为域范围的委派可能会在服务帐户遭到破坏的情况下带来安全风险。干杯
  • 我还需要创建一个 GSuite 帐户吗?常规似乎不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-19
  • 2022-01-11
  • 1970-01-01
  • 2020-09-10
  • 2020-08-22
  • 1970-01-01
  • 2013-07-23
相关资源
最近更新 更多