将谷歌的刷新访问令牌(离线)与凭据集成在一个功能中

时间:2021-01-05 21:20:30

标签: python google-api google-oauth google-calendar-api google-api-python-client

我正在尝试通过从 chrome 扩展程序到我的网站的 POST 调用来访问用户的 访问令牌,该用户已授予权限。因此,所有依赖于重定向和用户参与会话的 google 文档都不适合我。

我似乎无法弄清楚如何将 google 的 refresh access token 与存储在 db 中的用户凭据(client_id、client_secret、refresh_token、grant_type)集成。

@blueprint.route("Calendar", methods=['POST'])
def Calendar():

    flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES) #believe should be added or else flow would be undefined (even though not present in the code snippet)

    authorization_url, state = flow.authorization_url(
      # Enable offline access so that you can refresh an access token without
      # re-prompting the user for permission. Recommended for web server apps.
      access_type='offline',
      # Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes='true')

我尝试添加:

# Use the authorization server's response to fetch the OAuth 2.0 tokens.
authorization_response = flask.request.url
flow.fetch_token(authorization_response=authorization_response)
credentials = flow.credentials
flask.session['credentials'] = credentials

user = User.query.filter_by(email=email).first()  
with open('client_secret.json') as d:
    d = json.load(d)
service = build('calendar', 'v3', credentials=credentials)

&得到:

oauthlib.oauth2.rfc6749.errors.MismatchingStateError: (mismatching_state) CSRF Warning! State not equal in request and response.

1 个答案:

答案 0 :(得分:1)

遗憾的是,并非所有 Google 示例的创建方式都相同,而且 Google 日历示例中缺少您尝试执行的操作的示例。

尝试检查 Google Analytics quick start Python 此示例有一个非常好的示例,说明如何设置刷新令牌的存储以及如何在需要时使用它。

 # Prepare credentials, and authorize HTTP object with them.
  # If the credentials don't exist or are invalid run through the native client
  # flow. The Storage object will ensure that if successful the good
  # credentials will get written back to a file.
  storage = file.Storage('calendar.dat')
  credentials = storage.get()
  if credentials is None or credentials.invalid:
    credentials = tools.run_flow(flow, storage, flags)
  http = credentials.authorize(http=httplib2.Http())

Google drive sample 的示例也有类似的内容。

# 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)

我不是要您在这里切换 API,我只是建议您检查其他两个教程中授权代码的工作方式。您需要传递现有的日历范围,而不是驱动器或分析的范围。您用于访问事件的方法不会改变,您只会改变授权功能。

我不是 python 开发者,所以不能真正帮助你改变它。