问题的症结在于,运行以下命令时,我无法委派凭据在其他用户帐户中工作。唯一的在线示例是使用 JSON 服务帐户,而不是 oAuth 身份验证流程。
newcreds = creds.create_delegated('<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5f00002b3a2c2b2a2c3a2d2c3a3e2d3c3700001f383b3a29713d3c713a3b2a" rel="noreferrer noopener nofollow">[email protected]</a>')
AttributeError: 'Credentials' object has no attribute 'create_delegated'
我的代码的亮点如下,正常的凭据登录效果很好,但需要访问其他用户帐户......
#!/usr/bin/env python
from __future__ import print_function
import pickle
import os.path
import json
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import sys
print('test')
##VARS
SCOPES = ['https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/admin.directory.user']
creds = None
count = 0
##Google Creds
creds = None
if os.path.exists(os.path.dirname(os.path.abspath(__file__))+'/secrets/token.pickle'):
with open(os.path.dirname(os.path.abspath(__file__))+'/secrets/token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
os.path.dirname(os.path.abspath(__file__))+'/secrets/credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open(os.path.dirname(os.path.abspath(__file__))+'/secrets/token.pickle', 'wb') as token:
pickle.dump(creds, token)
newcreds = creds.create_delegated('<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e4bbbb908197909197819697818596878cbbbba485808096819797ca808b89858d8a" rel="noreferrer noopener nofollow">[email protected]</a>')
service = build('drive', 'v3', credentials=creds)
最佳答案
使用 Google-OAuth 2.0 管理用户
管理 GSuite 域用户必须分为两部分
Admin SDK创建用户、检索用户、更新用户等方法(基本上是管理员可以在 admin console 中执行的所有操作)在使用其凭据进行身份验证时可以由域管理员直接访问
GSuite 管理员无法直接访问涉及使用大多数其他 API(Drive API、Gmail API 等)和访问私有(private)用户数据的方法。
出于安全原因,后者必须通过 service account 执行.
- 创建(或更新)服务帐户时,管理员可以决定授予其哪些范围并执行 domain-wide delegation .
- 域范围委派意味着服务帐户可以代表域用户 impersonating他 - 即充当用户并获得与用户本人相同的用户数据访问权限。
- 使用服务帐户的身份验证流程与常见的 Google API 身份验证不同。
- 没有以相同的方式创建访问或刷新 token ,并且管理员的工作目录中没有存储
token.json
文件。 - 相反,在 GCP 控制台中创建服务帐号时,需要将服务帐号凭据作为
json
或p12
文件下载到工作目录。< - 对于使用 Python 定义的
json
凭据文件模拟的服务帐户:
from google.oauth2 import service_account
SCOPES = ['https://www.googleapis.com/auth/drive']
SERVICE_ACCOUNT_FILE = '/path/to/service.json'
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE, scopes=SCOPES)
delegated_credentials = credentials.with_subject('<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a3d6d0c6d1e3c6dbc2ced3cfc68dccd1c4" rel="noreferrer noopener nofollow">[email protected]</a>')
drive_service = googleapiclient.discovery.build(
'drive', 'v3', credentials=delegated_credentials)
with_subject
是使服务模拟用户的关键部分。
指定的范围必须与您在管理控制台中分配给服务帐号的范围一致。
使用服务帐号时,去掉正常认证的代码部分,即
creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('drive', 'v3', credentials=creds)
其他信息
如果您更喜欢使用 p12
凭据文件而不是 json
,则 with_subject
将通过 create_delegate
替换.
示例:
from googleapiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
# Email of the Service Account
SERVICE_ACCOUNT_EMAIL = 'YOUR SERVICE ACCOUNT EMAIL'
# Path to the Service Account's Private Key file
SERVICE_ACCOUNT_PKCS12_FILE_PATH = '/path/to/<public_key_fingerprint>-privatekey.p12'
def create_directory_service(user_email):
"""Build and returns an Admin SDK Directory service object authorized with the service accounts
that act on behalf of the given user.
Args:
user_email: The email of the user. Needs permissions to access the Admin APIs.
Returns:
Admin SDK directory service object.
"""
credentials = ServiceAccountCredentials.from_p12_keyfile(
SERVICE_ACCOUNT_EMAIL,
SERVICE_ACCOUNT_PKCS12_FILE_PATH,
'notasecret',
scopes=['https://www.googleapis.com/auth/drive'])
credentials = credentials.create_delegated(user_email)
return build('drive', 'v3', credentials=credentials)
关于api - 在 oAuth Google Api Flow 中使用 "create_delegated"时遇到问题....gDrive,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62045825/