Skip to main content
 首页 » 编程设计

python之unauthorized_client : Client is unauthorized to retrieve access tokens using this method

2025年05月04日10落叶

我是一名拥有近 300 名用户的 GSuite 管理员,我正在从 GSuite 迁移。我需要下载他们创建/上传的所有用户文件。

我从小处着手编写一个 Python 脚本,该脚本将在列表中显示用户文件,但似乎我被大量的授权问题困住了。

  1. 我在 Google 控制台中创建了一个项目,并创建了一个服务帐户,其中包含私钥(基于 json)并勾选了 GSuite 域范围内的委派复选框
  2. 在我的 GSuite 管理面板中,我在管理 API 访问中添加了新创建的客户端 ID 和权限范围:https://www.googleapis.com/auth/drive,https://www .googleapis.com/auth/admin.datatransfer,https://www.googleapis.com/auth/admin.directory.user,https://www.googleapis.com/auth/admin.directory.group

根据文档(https://developers.google.com/admin-sdk/directory/v1/guides/delegation)非常好

  1. 我正在从 ServiceAccountCredentials 创建一个资源对象,并分别基于 API 名称/版本“drive”和“v3”构建一个对象,并尝试根据 Google 的快速入门 (https://developers.google.com/drive/api/v3/quickstart/python) 获取文件列表:

     from googleapiclient.discovery import build 
     from oauth2client.service_account import ServiceAccountCredentials 
     
     SERVICE_ACCOUNT_EMAIL = "drive-getter@mygoogledomain.iam.gserviceaccount.com" 
     SERVICE_ACCOUNT_PKCS12 = "./service_key.json" 
     
     def create_directory_service(user_email): 
       credentials = ServiceAccountCredentials.from_json_keyfile_name(SERVICE_ACCOUNT_PKCS12, scopes=['https://www.googleapis.com/auth/drive']) 
       credentials = credentials.create_delegated(user_email) 
     
       return build('drive', 'v3', credentials=credentials) 
     
     
     resource = create_directory_service('username@mydomain.com') 
     
     results = resource.files().list( 
       pageSize=10, fields="nextPageToken, files(id, name)" 
     ).execute() 
     
     items = results.get('files', []) 
     
     print(items) 
    

它看起来完全正确,但我收到此错误消息:

Connected to pydev debugger (build 181.5087.37)

Traceback (most recent call last): File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1664, in main() File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1658, in main globals = debugger.run(setup['file'], None, None, is_module) File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1068, in run pydev_imports.execfile(file, globals, locals) # execute the script File "/Applications/PyCharm.app/Contents/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile exec(compile(contents+"\n", file, 'exec'), glob, loc) File "/Users/probe/Projects/drive_getter/src/dconnect.py", line 16, in pageSize=10, fields="nextPageToken, files(id, name)" File "/Users/probe/Projects/drive_getter/drive_getter/lib/python3.6/site-packages/googleapiclient/_helpers.py", line 130, in positional_wrapper return wrapped(*args, **kwargs) File "/Users/probe/Projects/drive_getter/drive_getter/lib/python3.6/site-packages/googleapiclient/http.py", line 835, in execute method=str(self.method), body=self.body, headers=self.headers) File "/Users/probe/Projects/drive_getter/drive_getter/lib/python3.6/site-packages/googleapiclient/http.py", line 162, in _retry_request resp, content = http.request(uri, method, *args, **kwargs) File "/Users/probe/Projects/drive_getter/drive_getter/lib/python3.6/site-packages/oauth2client/transport.py", line 159, in new_request credentials._refresh(orig_request_method) File "/Users/probe/Projects/drive_getter/drive_getter/lib/python3.6/site-packages/oauth2client/client.py", line 749, in _refresh self._do_refresh_request(http) File "/Users/probe/Projects/drive_getter/drive_getter/lib/python3.6/site-packages/oauth2client/client.py", line 819, in _do_refresh_request raise HttpAccessTokenRefreshError(error_msg, status=resp.status) oauth2client.client.HttpAccessTokenRefreshError: unauthorized_client: Client is unauthorized to retrieve access tokens using this method.

知道在这个过程中做错了什么吗?同样 - 我的目标是列出并稍后下载所有 GSuite 用户的所有用户文件,因此我考虑循环我的用户电子邮件并对所有用户应用相同的逻辑,直到我下载所有文件。

感谢合作!

请您参考如下方法:

Client is unauthorized to retrieve access tokens using this method.

Google Develoepr 控制台中有多种不同类型的客户端。

  • 浏览器 - 用于网络应用程序。
  • native - 用于已安装的应用程序
  • 服务帐户 - 用于服务器到服务器的通信
  • 手机

用于对这些不同类型进行身份验证的代码是不同的,这是可以理解的。

您使用的代码似乎是具有服务帐户的 Python 的正确代码。虽然 from_json_keyfile_name 接受 p12 文件而不是 .json 文件。

对于客户来说必须是正确的。返回 Google 开发者控制台创建服务帐户客户端并下载正确的 .json 文件。

Service account python

from google.oauth2 import service_account 
 
SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin'] 
SERVICE_ACCOUNT_FILE = '/path/to/service.json' 
 
credentials = service_account.Credentials.from_service_account_file( 
        SERVICE_ACCOUNT_FILE, scopes=SCOPES) 

我建议在 p12 文件上使用 .json 文件,我怀疑谷歌将在未来的某个时候停止使用这些文件。