- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用 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
看看这个问题,我可以找到两个方向:
offline=True
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/
我正在与一个显然需要 OAuth 身份验证的自定义 APEX 服务进行交互。我可以轻松地对我的应用程序进行身份验证和授权。一切正常。 但是,我收到的访问 token 往往会过期。 当然,我可以通过发送
我有一个使用 oauth2 连接到第三方应用程序的 C# 应用程序。首先,用户被重定向到一个外部应用程序 (ERP),他在其中输入用户名和密码,并生成一个有效期为 1 小时的访问 token 和一个有
我对 refresh_token 有疑问。我完全不明白。我读到我只在登录后第一次获得此 token ,之后不会返回 refresh_token。第一种方法是初始化 gapi: initGp: func
我有一个有两条路由的小型 express 服务器。然后它将 json token 写入文件(我知道非常不安全)。由于某种原因,没有 refresh_token。在文档中有一条评论说 offline f
我将 google API 用于个人项目,因此我的应用没有通过 google 验证。 我完全使用 this我自己的代码示例和登录时生成的 token.json 文件。一切正常,每次我发出请求(每 10
背景 我使用 google-api-python-client django_sample 获得了 Google API 的 access_token . 为了离线访问,我添加了 FLOW.param
我写了一个关于使用 google api 的例子。 Google NodeJS Client library .我遵循了指令集 access_type : 'offline',但是返回的对象不包含 r
我在 IdentityServer 4 中使用 .net 核心。我有一个 Web api 和一个访问 api 上的安全端点的 MVC 应用程序。它的设置与 IdentityServer 快速入门非常相
我正在阅读 OAuth2 规范: https://www.rfc-editor.org/rfc/rfc6749#section-4.4.2 特别是关于 client_credentials 的部分授予
我在Grails 3应用程序中使用Spring Security Rest发出“refresh_token”请求时遇到了一些麻烦。我有一个同时具有Web前端和一些Rest端点的应用程序,其他所有东西似
我正在使用的项目:来自 nuget 的 ImgurNet(来源:https://github.com/0xdeafcafe/ImgurNet) 它似乎需要所有这些参数: { "client_i
我对 refresh_token 流程(http://wiki.developerforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com)的
您好,我是计算机科学专业的学生,正在 oauth.io 上做一些实验。但我在成功获取代码后获取刷新 token 时遇到问题。获取代码后,我正在编写以下代码行,但它给了我内部服务器错误.. 代码是
我正在使用 omniauth-coinbase和 coinbase-ruby在我的 Rails 应用程序中。 在我的应用程序中,用户通过 Coinbase 登录,Coinbase 生成一个 code,
所以我通过这种方式获得了一个刷新 token ,我可以保留它吗? 如果可以,下次要怎么用才能不用开浏览器? 现在我正在考虑直接创建 OAuth2Credentials 对象,这是正确的方法吗? fro
我将 HWIO Bundle 用于 google api,当我收到来自 google refreshToken = null 的响应时,为什么?如何刷新 token oAuthToken = {HWI
如果用户的 access_token 过期并且用户想保持登录状态,我需要让用户在系统中保持登录状态。如何在 Keycloak 上使用 refresh_token 获取新更新的 access_token
我的 axios 响应中有以下拦截器: window.axios.interceptors.response.use( response => { return response; }
我正在使用 FLask Framework 构建网站 + 后端我在其中使用 Flask-OAuthlib与谷歌进行身份验证。身份验证后,后端需要定期扫描用户的 Gmail。因此,当前用户可以验证我的应
根据 https://groups.google.com/forum/#!forum/oauth2-dev讨论现在在这里。 无论我读了多少书,我都无法理解 google OAuth2 token 的工
我是一名优秀的程序员,十分优秀!