如何使用访问令牌获取 Google 日历事件
Posted
技术标签:
【中文标题】如何使用访问令牌获取 Google 日历事件【英文标题】:How to get Google-Calendar events using access token 【发布时间】:2021-12-13 07:36:58 【问题描述】:我已经构建了一个 django 应用程序,其中包括 google Oauth2.0 登录。 我想在每个用户使用 Oauth2.0 登录时获取他们的谷歌日历事件,我编写了以下代码。我将访问令牌保存到 UserAuth 表中并获取它,然后用它来获取谷歌日历。
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']">
有没有办法跳过这个问题?
【问题讨论】:
您能否提供更多有关您如何获得访问令牌的信息?为了获得它们,用户是否以自己的身份进行身份验证?如果您通过身份验证获得它,则访问令牌将只能访问您的帐户可以访问的事件。 是的,用户将使用他们的谷歌帐户登录,如 Oauth 登录,他们将获取他们的访问令牌。 【参考方案1】:你可以运行下面的代码。
def get_events_server(request):
SCOPES = ['https://www.googleapis.com/auth/calendar']
user = User.objects.get(username=request.user)
authuser = UserAuth.objects.get(user=user)
google_permission = authuser.google_permission
print(google_permission)
creds = None
if google_permission == True:
token_id = authuser.google_id_token
creds = Credentials(token_id, refresh_token=None, id_token=None, token_uri=None, client_id=None, client_secret=None, scopes=SCOPES, default_scopes=None, quota_project_id=None, expiry=None, rapt_token=None)
else:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
print("creds")
else:
CLIENT_SECRET_FILE = os.path.join(settings.BASE_DIR, '../key/client_secret_key.json')
flow = InstalledAppFlow.from_client_secrets_file(
CLIENT_SECRET_FILE, SCOPES)
#credentials = service_account.Credentials.from_service_account_file(CLIENT_SECRET_FILE)
#creds = tools.run_flow(flow, store)
flow.redirect_uri = 'https://google-oauth-django.herokuapp.com/calendar/'
flow.run_local_server(port=8080,open_browser=True)
creds = flow.credentials
print(creds.token)
authuser.google_permission = True
authuser.save()
service = build('calendar', 'v3', credentials=creds)
return service
这对我来说效果很好。
【讨论】:
你能把结果显示为截图吗?【参考方案2】:您在这里有点困惑,让我们先看看身份验证和授权之间的区别。
身份验证或 Open Id 连接正在登录,您让用户登录到他们的 google 帐户,您会得到一个 id 令牌,并且您可以访问他们的个人资料信息,因为用户已登录。您正在验证背后的用户机器拥有该帐户。在您的代码中查看您正在使用的 id_token 打开 id 连接以验证用户。
creds = UserAuth.objects.get(user=user).google_id_token
为了访问用户的私人数据,您的应用程序需要被授权访问该数据。授权由范围或您需要的访问范围定义。为了使用谷歌日历 API,您需要一个访问令牌,其范围将授予您访问用户谷歌日历事件的权限
您应该查看Python quickstart for google calendar,它将向您展示如何使用 Oauth2 让您的应用程序请求用户授权以访问他们的谷歌日历数据。
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', [])
来自 cmets
您的链接同意屏幕请求返回错误。这是重定向 uri 未匹配错误,它是您在设置 oauth2 时可能遇到的最常见错误之一。
如果您检查错误,它会告诉您此 url redirect_uri: http://localhost:61668/
存在问题,您正在从该 url 发送您的请求。这意味着您需要转到谷歌云控制台并将该重定向 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.
【讨论】:
我不确定应该从哪里获得 token.json 和 credentials.json?这个文件是我的访问令牌或用户令牌的信息吗? @DaimTo credentials.json 会在您在 Google Developer Console 上注册时在您的项目中创建。只需记住在 library 下启用 Google Calendar api。 token.json 是在用户第一次运行我们的应用程序时创建的,他们的凭据刷新令牌和访问令牌将存储在该文件中。我建议你按照它解释如何创建它们的快速入门。 我只是按照您的代码运行它,在这种情况下出现以下错误:请访问此 URL 以授权此应用程序:accounts.google.com/o/oauth2/… 检查我的更新。 我添加了redirect_uri,但出现了同样的错误。 @DalmTo以上是关于如何使用访问令牌获取 Google 日历事件的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 JavaScript 从 Google 日历页面获取事件 ID?
如何使用 Google Refresh Token 更新 Google Access Token
即使似乎授予访问权限,Google Calendar API在OAuth期间也会出现403错误