使用 Google oAuth 2.0 时新用户登录时刷新页面

Posted

技术标签:

【中文标题】使用 Google oAuth 2.0 时新用户登录时刷新页面【英文标题】:Refresh page on new user sign in when using Google oAuth 2.0 【发布时间】:2017-09-15 01:26:35 【问题描述】:

我正在尝试使用 Google Sign For Websites. 创建一个网站,主要是为了了解它的工作原理。

我已按照 Google 提供的教程中概述的步骤进行操作,效果很好。用户可以成功登录我的站点,它可以将用户 ID 传递到后端,然后使用 php 脚本验证 ID 服务器端。

Php 然后在网站上为用户创建一个会话。我想不通的是,当用户单击 Google 登录按钮并且登录成功时,我将如何刷新页面。刷新页面将允许主页重新加载新的 php 会话数据。

<div class="g-signin2 signin-button" data-onsuccess="onSignIn" data-theme="dark"></div>

function onSignIn(googleUser)

        // The ID token you need to pass to your backend:
        var id_token = googleUser.getAuthResponse().id_token;

        var xhr = new XMLHttpRequest();
        xhr.open('POST', 'https://mywebsite.com/tokensignin.php');
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.onload = function() 
            console.log('Signed in as: ' + xhr.responseText);
        ;
        xhr.send('idtoken=' + id_token);
      ;

我尝试在代码的 onload = function() 部分中简单地使用 location.reload()。这会导致页面在每次加载时都会无限刷新,但是因为 Google 每次都会通过此 xhr 变量验证用户是否已登录。

我已经尝试looking through their reference 使用GoogleAuth.isSignedIn.listen(listener) 来监控任何更改,但它似乎并没有完全满足我想要的,或者我没有正确使用它,因为我不完全知道监听器是什么应该是。

另一个选项可能是使用他们的GoogleAuth.attachClickHandler(container, options, onsuccess, onfailure) 函数,但我不完全确定如何正确配置选项字段/变量。

如果有人能提供一些关于这个世界如何运作的见解,我将不胜感激。

总结一下,如果用户已经使用谷歌登录到我的网站,我希望页面什么都不做,如果他们点击登录按钮,登录成功后我想刷新他们所在的页面。

【问题讨论】:

【参考方案1】:

您可以使用回调函数向 xhr 添加监听器。

xhr.addEventListener("load", loginComplete);

然后创建一个函数:

function loginComplete(evt) 
    console.log("Login Complete");
    window.location.reload(); 

编辑:

好的。由于听众没有帮助。您需要检查用户是否已经登录。要保存该信息,我能想到的一件事是使用 cookie。

因此您可以存储从 Google 收到的 Auth Token 并为其设置 cookie 并在每次发布 POST 之前检查。

这是一个不错的 js cookie 库:https://github.com/js-cookie/js-cookie

然后onload你保存id:

xhr.onload = function() 
    Cookie.set('google_token', id_token);
    window.location.reload();
;

onSignIn 函数如下:

function onSignIn(googleUser)
    var cookie = Cookie.get('google_token');
    if(cookie != undefined)
        //cookie is set
        return;
    
    ...
    //rest of the function

当然你需要改进这段代码,例如,检查存储在cookie中的令牌是否仍然有效,某些情况你可以刷新它而不是让用户重新登录(oAuth API提供了这样的东西) .

采取一些安全措施以确保令牌没有被注入等等。

【讨论】:

这仍然不能解决问题,因为它仍然会造成页面刷新的无限循环。单击按钮并完成登录时将触发刷新。但是,一旦刷新完成页面加载,它就会再次发送请求。由于每次加载页面时,Google 都会处理登录以查看用户是否仍登录到该站点。如果他们登录到站点,则登录成功完成。然后导致登录再次“完成”。 我会在接下来一两天有时间的时候尝试一下。我认为这可能会成为最可靠的方法。我在最后一天左右对 API 进行了一些额外的试验。有一些函数会查找用户状态的变化,例如 GoogleAuth.isSignedIn.listen,但这些函数会带来一些已经存在的问题。每次加载页面时都会检查状态变化的监听,再次创建无限循环的刷新。用于检查新登录和已登录的 cookie,以及用于验证数据的会话将是一种简单且安全的方法 您可以研究的另一个想法是使用框架来构建您的网站,例如 React 或 Vue。他们都有处理这种事情的包,还有更多。你做的工作太多了,你可能会专注于其他一些重要的事情。我个人使用 Laravel 来处理我所有的后端,包括基于令牌的身份验证,而且很容易让它工作...... 从长远来看,使用这些框架中的一个或组合是处理此类问题的最佳方式,我同意。原则上,虽然通过 cookie 处理此问题以确定新登录是我发现的最佳方法。人们应该遵循 Google API 文档来验证令牌是否有效且安全。所有这些的结合使它能够成功运行。感谢您的帮助。【参考方案2】:

为什么不让您的后端重定向(或发送信息以便页面可以在成功时重定向)?

重新加载登录屏幕需要什么?

您还可以查看侦听器文档,这似乎可以解决您想要的问题。 IE。监听用户变化并触发函数或重定向。

https://developers.google.com/identity/sign-in/web/listeners

【讨论】:

【参考方案3】:

我的方法和你的一样,我确实遇到了同样的问题,不断刷新。

我尝试了几种解决方案,效果最好的一个如下:

用户登录使用 GAPI2 触发回调onGoogleSignIn 后端检查 ID 令牌的有效性,并通过我的 webapp 上的会话登录用户 如果成功,我将用户注销使用 GAPI2,防止无限重新加载,因为永远不会再次调用 onGoogleSignIn 然后我刷新页面并将登录按钮替换为我的 web 应用程序的注销按钮

如果您想操纵用户 Google 帐户上的某些数据,这个解决方案当然几乎没有用,但我发现这个功能没有用处。


用于让某人退出其 Google 帐户的代码。

function signOut() 
    var auth2 = gapi.auth2.getAuthInstance();
    auth2.signOut().then(function () 
        console.log('User signed out.');
    );

【讨论】:

以上是关于使用 Google oAuth 2.0 时新用户登录时刷新页面的主要内容,如果未能解决你的问题,请参考以下文章

OAuth 2.0介绍

OAuth 2.0 授权认证详解

从 Google OAuth 2.0 PHP API 获取用户信息

OAuth 2.0

在弹出窗口中打开 Google SignIn 用户身份验证,需要使用 OAuth 2.0 在同一选项卡本身中打开

Google oauth 2.0 API 密码更改用户名和密码不被接受