如何刷新过期的 google 登录?

How to refresh expired google sign-in logins?

我正在使用 Google 登录。用户访问我的站点并使用 gapi.auth2.getAuthInstance().signIn() 登录,或者他们已经登录并且当页面加载(或重新加载)时我们获取状态。此时我有一个可以在服务器上验证一个小时的身份令牌。

当用户离开浏览器(例如,一夜之间)时,此令牌将过期。 gapi.auth2.getAuthInstance().isSignedIn.get() returns 正确,但令牌未验证。

如何登录用户并在他们的会话处于活动状态(即浏览器未关闭)时让他们保持登录状态?或者刷新令牌?任何比重新加载页面更优雅的事情...

编辑:刷新令牌不是正确答案;我不想离线访问(也不想请求许可)。 Google 显然认为用户仍然登录到我的应用程序;用户可以重新加载页面并获取新令牌,而无需再次提供凭据。肯定有比隐藏的 iframe 更优雅的机制来获取更新的令牌?

您可以使用刷新令牌获得离线访问。根据官方参考

Access tokens have limited lifetimes. If your application needs access to a Google API beyond the lifetime of a single access token, it can obtain a refresh token. A refresh token allows your application to obtain new access tokens.

基本上您会在第一次请求身份验证时得到 refresh token。您需要安全地保存该令牌以备将来使用。 access token(您提到的身份令牌)在一小时后到期。之后,每次想要获得新的可用 access token 时,都必须使用 refresh token

根据您使用的客户端库,语法会有所不同。以下是 php 客户端库的示例。

// get access token from refresh token if access token expire

if($client->getAuth()->isAccessTokenExpired()) {
    $client->refreshToken($securelyPreservedRefreshToken);
    $newToken = $client->getAccessToken();
}

检查 this 了解详细步骤。

FWIW,我们已经设法(大部分)通过 listener approach 使其工作。似乎在访问令牌过期前约 5 分钟调用了 'userChanged' 回调。这足以让我们在不刷新页面的情况下提取和更新访问令牌。

当计算机从睡眠状态恢复时,不太有效。这可以通过 reloading the page on wake up.

相对容易地解决

您可以使用 listeners 完成此操作。

var auth2 = gapi.auth2.getAuthInstance();

// Listen for changes to current user.
// (called shortly before expiration)
auth2.currentUser.listen(function(user){

    // use new user in your OpenID Connect flow

});

这将允许您保留当前凭据,只要浏览器保持活动状态。

如果计算机进入睡眠状态,则必须完成额外的工作以获取当前凭据。

if (auth2.isSignedIn.get() == true) {
    auth2.signIn();
}

如果token过期,可以调用gapi.auth2.getAuthInstance().currentUser.get().reloadAuthResponse()。它 returns 一个承诺。

我提出了一个 issue with Google over this 因为他们没有正确记录这简直是荒谬。

My comment here 建议我如何使用上述方法完成刷新。