1

嗨,我正在使用 authlib/FastAPI/Google 开发一个用于登录过程的网络应用程序,并希望保留refresh_token这样我可以让用户在应用程序中保持足够的时间。

我遵循了https://docs.authlib.org/en/latest/client/starlette.html中的标准程序

oauth = OAuth()
oauth.register(
  name='google',
  client_id='xxx',
  client_secret='yyy',
  api_base_url='https://www.googleapis.com/oauth2/v3/',
  access_token_url='https://accounts.google.com/o/oauth2/token',
  authorize_url='https://accounts.google.com/o/oauth2/auth',
  jwks_uri='https://www.googleapis.com/oauth2/v3/certs',
  client_kwargs={
    'scope': 'email openid',
    'access_type': 'offline',
    'prompt': 'consent',
  }
)

from starlette.requests import Request

@app.get("/login")
def login_via_google(request: Request):
    redirect_uri = 'https://example.com/auth'
    return await oauth.google.authorize_redirect(request, redirect_uri)

@app.get("/auth")
def auth_via_google(request: Request):
    token = await oauth.google.authorize_access_token(request)
    user = await oauth.google.parse_id_token(request, token)
    return dict(user)

但是,refresh_token即使我指定了access_type='offline'. 如果我的应用程序已经在我的帐户中注册,我也添加了一个参数prompt='content'

我错过了什么吗?

此外,保持refresh_token一个长期运行的用户应用程序的最佳方式是什么?我不喜欢打扰用户多次登录。

提前致谢!

4

3 回答 3

1

我自己遇到了这个问题,在调试器中挖掘代码,结果发现,authorize_redirect如果在此之前没有消耗它们,函数的任何额外关键字参数最终都会作为 url 上的参数。

因此,解决该问题的一个简单方法就是将该调用修改为

return await oauth.google.authorize_redirect(request, redirect_uri, access_type="offline")
于 2021-08-26T07:34:23.777 回答
0

我也遇到了这个问题。似乎只允许一些参数client_kwargs

EXTRA_AUTHORIZE_PARAMS = (
    'response_mode', 'nonce', 'prompt', 'login_hint'
)

也许作者试图禁止特定于实现的参数?一种解决方法似乎是将其添加access_type=offlineauthorize_url

authorize_url='https://accounts.google.com/o/oauth2/auth?access_type=offline'
于 2020-06-15T04:42:01.187 回答
0

大多数脚本语言仅在用户第一次通过身份验证时返回 refresh_token。假设您已将其保存在系统中并正在使用它,因此不需要另一个。因此,所有其他对用户进行身份验证的尝试都不会包括它。

您可以尝试强制他们重新同意,但我不确定这是否会强制使用新的刷新令牌。看起来你正在这样做,所以它不起作用。

在这种情况下,您可能需要撤销用户访问权限并再次请求。除非你有令牌然后令牌撤销然后让他们再次登录,你应该看到一个刷新令牌

如果一切都失败了,让用户进入他们的谷歌帐户并删除您的应用程序对其帐户的访问权限,然后尝试登录。这就像完全重新开始,并且会挑衅地给你一个刷新令牌。

于 2020-03-06T07:04:02.693 回答