gpt4 book ai didi

python - 使用 Flask-dance 和 Google oauth 获取 'Missing required parameter: refresh_token'

转载 作者:太空宇宙 更新时间:2023-11-03 20:32:09 33 4
gpt4 key购买 nike

我正在使用 Flask-dance 来验证我的应用程序的用户身份。身份验证提供商是 Google。

有时会引发以下异常:

2019-08-09 08:07:26 default[20190809t105407]  "GET / HTTP/1.1" 500
2019-08-09 08:07:26 default[20190809t105407] -- 0 --
2019-08-09 08:07:26 default[20190809t105407] -- 1 --
2019-08-09 08:07:27 default[20190809t105407] InvalidClientIdError was caught: (invalid_request) Missing required parameter: refresh_token

看看这个问题,我可以找到两个方向:

  1. 创建 Google 蓝图时使用 offline=True
  2. TokenExpiredError 实现错误处理程序

我做了这两项操作并将我的应用程序部署到 GAE,但我仍然面临相同的错误。从堆栈跟踪中,我了解到错误处理程序正在被调用,但是当代码尝试恢复时,会引发“refresh_token”

我的代码:(代码基于Google QuickStart和Flask-dance问题143)

import oauthlib
from flask import Flask, redirect, url_for, flash, session, current_app
from flask_dance.contrib.google import make_google_blueprint, google
import os
import time
from oauthlib.oauth2.rfc6749.errors import InvalidClientIdError, TokenExpiredError

GOOGLE_CLIENT_ID = os.environ.get("GOOGLE_CLIENT_ID", None)
GOOGLE_CLIENT_SECRET = os.environ.get("GOOGLE_CLIENT_SECRET", None)

app = Flask(__name__)
app.secret_key = "TODO_TODO"
blueprint = make_google_blueprint(
client_id=GOOGLE_CLIENT_ID,
client_secret=GOOGLE_CLIENT_SECRET,
offline=True
)
app.register_blueprint(blueprint, url_prefix="/login")


@app.route('/logout', methods=['GET'])
def logout():
_revoke_token_and_empty_session()
return redirect(url_for('app.index'))


def _revoke_token_and_empty_session():
print('inside _revoke_token_and_empty_session')
if google.authorized:
try:
google.get(
'https://accounts.google.com/o/oauth2/revoke',
params={
'token':
current_app.blueprints['google'].token['access_token']},
)
except TokenExpiredError:
pass
except InvalidClientIdError:
# Our OAuth session apparently expired. We could renew the token
# and logout again but that seems a bit silly, so for now fake
# it.
pass
session.clear()


@app.errorhandler(oauthlib.oauth2.rfc6749.errors.TokenExpiredError)
def token_expired(_):
print('In TokenExpiredError')
del blueprint.token
_revoke_token_and_empty_session()
flash('Your session had expired. Please submit the request again',
'error')
return redirect(url_for('app.index'))


@app.route("/")
def index():
print('-- 0 --')
if not google.authorized:
return redirect(url_for("google.login"))
print('-- 1 --')
user_info_url = 'https://openidconnect.googleapis.com/v1/userinfo'
try:
resp = google.get(user_info_url)
except InvalidClientIdError as e:
#
# Here is the problem
#
print('InvalidClientIdError was caught: {}'.format(str(e)))
return 'Having an InvalidClientIdError issue: {}'.format(str(e)), 500
else:
print('-- 2 --')
user_info = resp.json()
return "You are {user_name} on Google. Time: {t}".format(user_name=user_info['name'], t=time.time())


if __name__ == "__main__":
app.run()

我目前的理解是捕获了TokenExpiredError并调用了index函数。当函数尝试调用 resp = google.get(user_info_url) 时,会引发 InvalidClientIdError: (invalid_request) Missing required parameter:fresh_token

知道如何解决吗?

最佳答案

从您的代码和 Flask 代码来看,您似乎正在尝试在撤销 token 之前删除该 token ,即使它已经无效。如果您想避免传递“offline=True”,请尝试简化代码,因为不需要刷新任何内容(用户将被重定向),并且 token 已经无效,因此撤销没有多大意义也可以。我还只设置了一个错误处理程序。

这是对我有用的代码:

import oauthlib
from flask import Flask, redirect, url_for, flash, session, current_app
from flask_dance.contrib.google import make_google_blueprint, google
import os
import time
from oauthlib.oauth2.rfc6749.errors import InvalidClientIdError, TokenExpiredError

GOOGLE_CLIENT_ID = os.environ.get("GOOGLE_CLIENT_ID", None)
GOOGLE_CLIENT_SECRET = os.environ.get("GOOGLE_CLIENT_SECRET", None)

app = Flask(__name__)
app.secret_key = "TODO_TODO"
blueprint = make_google_blueprint(
client_id=GOOGLE_CLIENT_ID,
client_secret=GOOGLE_CLIENT_SECRET,
offline=True
)
app.register_blueprint(blueprint, url_prefix="/login")


@app.route('/logout', methods=['GET'])
def logout():
"""
This endpoint tries to revoke the token
and then it clears the session
"""
if google.authorized:
try:
google.get(
'https://accounts.google.com/o/oauth2/revoke',
params={
'token':
current_app.blueprints['google'].token['access_token']},
)
except TokenExpiredError:
pass
except InvalidClientIdError:
# Our OAuth session apparently expired. We could renew the token
# and logout again but that seems a bit silly, so for now fake
# it.
pass
_empty_session()
return redirect(url_for('app.index'))


def _empty_session():
"""
Deletes the google token and clears the session
"""
if 'google' in current_app.blueprints and hasattr(current_app.blueprints['google'], 'token'):
del current_app.blueprints['google'].token
session.clear()


@app.errorhandler(oauthlib.oauth2.rfc6749.errors.TokenExpiredError)
@app.errorhandler(oauthlib.oauth2.rfc6749.errors.InvalidClientIdError)
def token_expired(_):
_empty_session()
return redirect(url_for('app.index'))

@app.route("/")
def index():
print('-- 0 --')
if not google.authorized:
return redirect(url_for("google.login"))
print('-- 1 --')
user_info_url = 'https://openidconnect.googleapis.com/v1/userinfo'
resp = google.get(user_info_url)
user_info = resp.json()
return "You are {user_name} on Google. Time: {t}".format(user_name=user_info['name'], t=time.time())


if __name__ == "__main__":
app.run()

关于python - 使用 Flask-dance 和 Google oauth 获取 'Missing required parameter: refresh_token',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57424318/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com