为啥刷新令牌过期不返回?

Posted

技术标签:

【中文标题】为啥刷新令牌过期不返回?【英文标题】:Why is the expiration of the refresh token not returned?为什么刷新令牌过期不返回? 【发布时间】:2016-05-30 14:33:13 【问题描述】:

请求访问/刷新令牌时,会发送刷新令牌,但 API 响应中缺少“refresh_token_expires_in”属性。我不知道官方过期时间戳是什么。为什么缺少记录的属性?

对于授权类型“authorization_code”和“refresh_token”授权请求,我收到相同的响应正文。以下是我收到的示例。

  
   "token_type": "Bearer",
   "expires_in": "3599",
   "scope": "Calendars.Read Calendars.ReadWrite Files.Read Files.ReadWrite User.Read User.Read.All",
   "expires_on": "1455797016",
   "not_before": "1455793116",
   "resource": "https://graph.microsoft.com/",
   "access_token": "eyJ0eXAiOiJKV1QiL...",
   "refresh_token": "AAABAAAAiL9Kn2Z27Uub..."

如您所见,仅包含访问令牌过期时间。一个额外的问题是这个“not_before”是什么?我找不到有关此属性含义的参考。

http://graph.microsoft.io/en-us/docs/authorization/app_authorization 使用刷新令牌更新过期的访问令牌 "新的过期时间是从令牌刷新请求成功提交开始的秒数,分别在 expires_in 和 refresh_token_expires_in 值中指定。"

“获取访问令牌”部分甚至指出:“在任何生产代码中,您的应用都需要观察这些令牌的到期情况,并在刷新令牌到期之前更新即将到期的访问令牌。”但是,它似乎没有给出我应该监控的过期时间。

getHub 上似乎有一个未解决的问题 https://github.com/OfficeDev/microsoft-graph-docs/issues/115

【问题讨论】:

hmmm... 2016 年 2 月 18 日 20:48 CET siewmoi 从文档示例中删除了“refresh_token_expires_in”。显然,graphAPI 文档已更改为当前行为,而不是将其视为用户应该期望的定义。 API 文档仍被视为产品是测试版。 您不能只使用访问令牌的 expires_on 值来确定何时使用您获得的刷新令牌吗?即,如果访问令牌只剩下(比如说)5 分钟的生命,使用刷新令牌来获取另一个? 您如何确定何时无法使用此刷新令牌来执行此访问令牌检索?我遇到的问题是我有一个漫长的过程和广泛的同步。它要运行一整夜,但是如果此刷新令牌在此过程中消失,那么这可能是一个问题。能够检测到令牌将无法在该过程中存活将允许人们在开始之前发出警告。但是,当请求新的访问令牌时,似乎刷新令牌可能会更新。对我来说,这一切都没有实际意义,因为我希望转换为用户凭据身份验证流程。 另外,当我们刷新时,我们会得到一个新的刷新令牌 - 后续刷新会延长寿命还是同时过期? 你知道日期"expires_on": "1455797016"的格式是那个Iso吗? 【参考方案1】:

您可以在关闭或过期时检查过期时间,使用刷新令牌请求新的访问令牌:

// Get current time + 5 minutes (to allow for time differences)
$now = time() + 300;
if ($token->expires <= $now) 
    // Token is expired (or very close to it) so let's refresh

    // Initialize the OAuth client
    $oauthClient = new GenericProvider([
        'clientId'                => config('msgraph.clientId'),
        'clientSecret'            => config('msgraph.clientSecret'),
        'redirectUri'             => config('msgraph.redirectUri'),
        'urlAuthorize'            => config('msgraph.urlAuthorize'),
        'urlAccessToken'          => config('msgraph.urlAccessToken'),
        'urlResourceOwnerDetails' => config('msgraph.urlResourceOwnerDetails'),
        'scopes'                  => config('msgraph.scopes')
    ]);

    $newToken = $oauthClient->getAccessToken('refresh_token', ['refresh_token' => $token->refresh_token]);

    return $newToken->getToken();

这个例子取自一个 Laravel 实现,但说明了这个想法。

【讨论】:

你完全没有抓住重点!投诉不知道刷新令牌何时到期。您的代码只是处理令牌过期而不是刷新令牌。当刷新令牌过期时,getAccessToken 将失败。知道这将发生在可能无法或不需要获取新刷新令牌的过程中(例如出于安全考虑)会很有用

以上是关于为啥刷新令牌过期不返回?的主要内容,如果未能解决你的问题,请参考以下文章

Google 令牌刷新返回“令牌已过期或撤销”。

为啥在每个请求上刷新 JUST 令牌是个坏主意?

仅在刷新页面时令牌过期时注销?为啥?

当我使用旧的刷新令牌时,为啥刷新端点会返回新的令牌?

为啥刷新令牌会在 14 天后过期

刷新令牌过期时间谷歌日历