0

我正在使用JavaScript的Google登录客户端API。我正在处理的网站有两个相关页面。它有一个登录页面,它有一个用户配置文件页面。登录页面显然有一个Google登录按钮。您只能在登录时查看您的配置文件页面。当用户未登录时转到其配置文件页面时,应将其重定向到登录页面。如何检测到您使用Google登录API注销?

这里有一个方法我都试过,没有工作:

// This does not work because this event is only fired when the user logs in or logs out, but not when the user is already logged out. 
gapi.auth2.init().isSignedIn.listen(function(state) { 
    if(!state) location.href = "/login/"; 
}); 

我也曾尝试检测用户的登录状态时,脚本加载,但也不能工作。它总是被重定向到登录页面,因为在脚本完成加载之前,Google API不能登录用户。

此外,我试图在我的代码中不使用setIntervalsetTimeout,但如果这是我唯一有效的选项,请通知我。

顺便说一句,我听说过多次,我可以设置一个变量,当用户登录,然后简单地重定向到登录页面,如果变量是false。我何时会检查所述变量的值?这不起作用,因为它需要我设置一个具体的延迟setTimeout。 Google的加载时间差异很大,所以我不打算使用它。

回答

1

我发现你可以使用这个简单的代码行来返回truefalse,这取决于用户是否在你的网站上登录Google。

gapi.auth2.init().isSignedIn.get(); 
1

我不是Google登录API方面的专家,但是从我所知道的API纯粹是为了验证目的以及(据我所知,我可能是错的)而不是实际的用户会话。与用户帐户有关的所有其他信息(IE,存储和持久登录会话)由您(开发人员)处理。基本身份验证支持通过data-onsuccess成功登录时调用回调函数,该函数在登录时使用相关的登录信息调用JavaScript函数。当用户登录时,标准做法是验证返回的用户令牌的有效性,然后您可以根据数据执行所需的操作。在这种情况下,您会为用户启动某种会话。

一个非常简单的例子如下:

首页

<!DOCTYPE html> 
<html> 
    <head> 
     <title>Test Home</title> 
    </head> 
    <body> 
     <a href="/login">Login</a><br> 
     <a href="/profile">Profile</a> 
    </body> 
</html> 

这有2个链接,一个轮廓和一个登录页面。

登录/ index.php文件

<!DOCTYPE html> 
<html> 
    <head> 
     <title>Test Login</title> 
     <meta name="google-signin-client_id" content="YOUR-CLIENT-ID.apps.googleusercontent.com"> 
    </head> 
    <body> 
     <div class="g-signin2" data-onsuccess="onLoginSuccess"></div> 

     <script type="text/javascript"> 
      function onLoginSuccess(user) { 
       var user_id_token = user.getAuthResponse().id_token, 
        request = new XMLHttpRequest(); 
       request.open('POST', 'https://www.googleapis.com/oauth2/v3/tokeninfo'); 
       request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
       request.onload = function() { 
        authUser(request.responseText); 
       }; 
       request.send('id_token=' + user_id_token); 
      } 
      function authUser(userData) { 
       var request = new XMLHttpRequest(); 
       request.open('POST', '/login/login.php'); 
       request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
       request.onload = function() { 
        if (request.responseText == 'true') { 
         location.href = "/"; 
        } 
       }; 
       request.send('user_data=' + userData); 
      } 
     </script> 
     <script src="https://apis.google.com/js/platform.js" async defer></script> 
    </body> 
</html> 

这是什么东西做的是创造一个非常基本的登录按钮。该按钮的回调为onLoginSuccess,当用户使用Google登录时会调用该回调。然后它通过user.getAuthResponse().id_token获取用户令牌,并向https://www.googleapis.com/oauth2/v3/tokeninfo发出发布请求以验证令牌(这可以在您的后端本地完成,Google为其提供了库,但使用API​​端点更容易)。验证完成后,它将响应数据发送到另一个函数authUser,然后将其传递到后端(/login/login.php)以实际启动用户会话。

登录/登录。PHP

<?php 

session_start(); 

$user_data = json_decode($_POST['user_data']); 

$_SESSION['user_data'] = $user_data; 

echo 'true'; 

login.php简单地启动一个会话,抓住发布的数据,并将用户会话发布的数据。然后它会回应true,以便JavaScript知道它已完成。 JavaScript然后将用户发回主页。

资料/ index.php文件

<?php 

session_start(); 

if (!isset($_SESSION['user_data'])) { 
    header('Location: /login'); 
} 

?> 

<!DOCTYPE html> 
<html> 
    <head> 
     <title>Test Profile</title> 
    </head> 
    <body> 
     <img src=<?php echo $_SESSION['user_data']->picture; ?>><br> 
     <b>Welcome! <?php echo $_SESSION['user_data']->name; ?></b><br> 
     <a href="/login/logout.php">Sign out</a> 
    </body> 
</html> 

什么此页是第一次检查,如果user_data会话设置。如果未设置(表示用户尚未登录),则会将其重定向回主页。如果已设置(表示已登录),则会显示一张图片和用户名,并具有一个logout按钮。当点击它时,它只会将用户带到/login/logout.php

登录/ logout.php

<?php 

session_start(); 

if (isset($_COOKIE[session_name()])) { 
    setcookie(session_name(), '', time()-3600, '/'); 
} 
session_destroy(); 

header('Location: /'); 

它所做的就是删除所有会话数据的用户,首先摆脱会话cookie,然后摧毁实际会话。然后引导他们回到主页。点击profile现在不会允许他们查看什么,因为他们登出,并且只显示数据,当他们重新登录。

这仅仅是一个非常基本和粗糙处理用户会话与方式Google API。有更好的方法(因为这个例子在后端没有真正的验证,并且会话在浏览器关闭时被终止,所以cookie可能对你更好),但这是处理用户会话的一般基础。

+0

虽然这是一个可能会起作用的解决方案,但我必须指出,Google API实际上为您处理了登录会话_does_。如果您在两个不同的页面上使用Google登录按钮,则登录时会自动将您登录到另一页面上。 –

+0

我几乎没有使用API​​,所以我对它的知识相当有限。然而,在我测试时(针对我发布的答案),我发现Google登录会话没有持续,并且每次访问该页面时都会提示登录Google。正因为如此,我被要求在本地存储会话。但即便如此,所提供的答案在技术上仍然可以回答这个问题,因为登录不仅被存储并持续存在,而且会在后端为用户提供信息。但是谢谢你的提示。 – LordBingShipley

+0

如果Google登录按钮放置在实际的域(不是'localhost'或本地HTML文件)上,Google将只处理登录会话。 –