Google服务帐户无法模拟GSuite用户

发布于 2021-01-29 15:00:49

from google.oauth2 import service_account
import googleapiclient.discovery

SCOPES = ['https://www.googleapis.com/auth/calendar']
SERVICE_ACCOUNT_FILE = 'GOOGLE_SECRET.json'

credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

delegated_credentials = credentials.with_subject('address@example.com')

google_calendar = googleapiclient.discovery.build('calendar', 'v3', credentials=delegated_credentials)

events = google_calendar.events().list(
    calendarId='address@example.com',
    maxResults=10
).execute()

上述代码的结果是:

google.auth.exceptions.RefreshError: ('unauthorized_client: Client is unauthorized to retrieve access tokens using this method.', '{\n  "error" : "unauthorized_client",\n  "error_description" : "Client is unauthorized to retrieve access tokens using this method."\n}')

Domain-wide delegation开启。服务帐户客户ID已在GSuite中使用适当的范围进行了授权。

该服务帐户可用于普通凭据。它仅不适用于委托凭证。

我在我们的域中尝试了不同的API(作用域)和不同的用户。

我有一个同事尝试从头开始编写示例,他得到了同样的东西。

关注者
0
被浏览
93
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    我认为您的问题是,在调用Calendar
    API
    之前,您没有对凭据进行授权,但是我在自己的实现中使用了一些区别

    • 使用以下导入语句

      from oauth2client.service_account import ServiceAccountCredentials
      

      from apiclient import discovery

    • 使用from_json_keyfile_name方法

    • 授权凭证,并http在构建服务时将其作为参数传递

    尝试对您的代码进行此修改:

    from apiclient import discovery
    from oauth2client.service_account import ServiceAccountCredentials
    import httplib2
    
    SCOPES = ['https://www.googleapis.com/auth/calendar']
    SERVICE_ACCOUNT_FILE = 'GOOGLE_SECRET.json'
    
    credentials = ServiceAccountCredentials.from_json_keyfile_name(
            SERVICE_ACCOUNT_FILE, scopes=SCOPES)
    
    # Use the create_delegated() method and authorize the delegated credentials
    delegated_credentials = credentials.create_delegated('address@example.com')  
    delegated_http = delegated_credentials.authorize(httplib2.Http())
    google_calendar = discovery.build('calendar', 'v3', http=delegated_http)
    
    events = google_calendar.events().list(
        calendarId='address@example.com',
        maxResults=10
    ).execute()
    

    我也建议calendarId='primary'您在API调用中进行设置,以便始终返回当前为其委派了凭据的用户的主日历。

    有关使用进行身份验证的更多信息,ServiceAccountCredentials请参见以下链接:http
    :
    //oauth2client.readthedocs.io/en/latest/source/oauth2client.service_account.html



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看