如何使用访问令牌获取 Google-日历事件

How to get Google-Calendar events using access token

我构建了一个 django 应用程序,其中包含 google Oauth2.0 登录。 我想在每个用户使用 Oauth2.0 登录时获取他们的 google 日历事件,我编写了以下代码。我将访问令牌保存到 UserAuth table 中并获取它,然后用它来获取 google 日历。

def get_events_server(request):
    user = User.objects.get(username=request.user)
    creds = UserAuth.objects.get(user=user).google_id_token

    credentials = AccessTokenCredentials(creds, "")
    http = httplib2.Http()
    http = credentials.authorize(http)

    service = build('calendar', 'v3', http=http)
    return service

当我运行代码的时候,出现了下面的错误。

HttpError at /calendar/
<HttpError 403 when requesting https://www.googleapis.com/calendar/v3/calendars/primary/events?timeMin=2021-10-28T04%3A33%3A08.956703Z&timeMax=2021-11-04T04%3A33%3A08.956712Z&singleEvents=true&timeZone=GMT%2B9%3A00&orderBy=startTime&alt=json returned "Request had insufficient authentication scopes.". Details: "[{'message': 'Insufficient Permission', 'domain': 'global', 'reason': 'insufficientPermissions'}]">

有没有办法跳过这个问题?

这里你有点糊涂了,让我们先看看身份验证和授权的区别。

身份验证或 Open Id connect 正在登录您让用户登录他们的 google 帐户,您将获得一个 ID 令牌,并且您可以访问他们的个人资料信息,因为用户已登录。您是身份验证机器后面的用户拥有该帐户。在您的代码中看到 id_token 您正在使用 Open id 连接来验证用户。

creds = UserAuth.objects.get(user=user).google_id_token

为了访问用户的私人数据,您的应用程序需要获得访问该数据的授权。授权由范围或您需要的访问范围定义。为了使用 google 日历 api,您需要一个访问令牌,其范围允许您访问用户 google 日历事件

您应该看看 Python quickstart for google calendar 它会告诉您如何使用 Oauth2 让您的应用程序请求用户授权以访问他们的 google 日历数据。

def main():
    """Shows basic usage of the Google Calendar API.
    Prints the start and name of the next 10 events on the user's calendar.
    """
    creds = None
    # The file token.json 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.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # 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.json', 'w') as token:
            token.write(creds.to_json())

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

    # Call the Calendar API
    now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time
    print('Getting the upcoming 10 events')
    events_result = service.events().list(calendarId='primary', timeMin=now,
                                        maxResults=10, singleEvents=True,
                                        orderBy='startTime').execute()
    events = events_result.get('items', [])

来自评论

您的 link 同意屏幕请求返回错误。这是重定向 uri 未匹配错误,它是您在设置 oauth2 时可能遇到的最常见错误之一。

如果您检查错误,它告诉您这个 url redirect_uri: http://localhost:61668/ 有问题,您正在从那个 url 发送您的请求。这意味着您需要转到 google 云控制台并将该重定向 uri 添加到您接受的重定向 uri 列表中。请记住,它必须完全匹配,因此必须包含端口号和尾部斜杠。

这些是您当前需要添加的重定向 URI http://localhost:61668/

尝试设置

flow.run_local_server(port=0)

flow.run_local_server(port=8000)

然后添加

http://localhost:8000/

作为您的重定向 uri。

如果您不知道该视频将向您展示如何修复它。 Google OAuth2: How the fix redirect_uri_mismatch error. Part 2 server sided web applications.