首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Google-plus登录:代码运行两次,用户登录后立即退出。

Google-plus登录:代码运行两次,用户登录后立即退出。
EN

Stack Overflow用户
提问于 2014-07-07 10:24:14
回答 2查看 929关注 0票数 7

这是一个建立在示例上的页面

代码语言:javascript
复制
<html>
<head>
  <title>Demo: Getting an email address using the Google+ Sign-in button</title>
  <style type="text/css">
  html, body { margin: 0; padding: 0; }
  .hide { display: none;}
  .show { display: block;}
  </style>
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" ></script>
  <!--<script src="https://apis.google.com/js/plusone.js" type="text/javascript"></script>-->
  <script src="https://apis.google.com/js/client:plusone.js" type="text/javascript"></script>
  <script type="text/javascript">
  /*
   * Triggered when the user accepts the sign in, cancels, or closes the
   * authorization dialog.
   */
  function loginFinishedCallback(authResult) {
    if (authResult) {

       console.log('authResult : ',authResult);
      if (authResult['error'] == undefined){
        gapi.auth.setToken(authResult); // Store the returned token.
        toggleElement('signin-button'); // Hide the sign-in button after successfully signing in the user.
        getEmail();                     // Trigger request to get the email address.
      } else {
        console.log('An error occurred');
      }
    } else {
      console.log('Empty authResult');  // Something went wrong
    }
  }

  /*
   * Initiates the request to the userinfo endpoint to get the user's email
   * address. This function relies on the gapi.auth.setToken containing a valid
   * OAuth access token.
   *
   * When the request completes, the getEmailCallback is triggered and passed
   * the result of the request.
   */
  function getEmail(){
    // Load the oauth2 libraries to enable the userinfo methods.
    gapi.client.load('oauth2', 'v2', function() {
          var request = gapi.client.oauth2.userinfo.get();
          request.execute(getEmailCallback);
        });
  }

  function getEmailCallback(obj){
    var el = document.getElementById('email');
    var email = '';
    console.log("OBJ = ",obj)
    if (obj['email']) {
      email = 'Email: ' + obj['email'];
    }

    //console.log(obj);   // Uncomment to inspect the full object.

    el.innerHTML = email;
    toggleElement('email');
  }

  function toggleElement(id) {
    var el = document.getElementById(id);
    if (el.getAttribute('class') == 'hide') {
      el.setAttribute('class', 'show');
    } else {
      el.setAttribute('class', 'hide');
    }
  }
  </script>
</head>
<body>
  <div id="signin-button" class="show">
     <div class="g-signin" data-callback="loginFinishedCallback"
      data-approvalprompt="auto"
      data-clientId="751931329576.apps.googleusercontent.com"
      data-scope="https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email"
      data-height="short"
      data-cookiepolicy="http://semicon-equip.com"
      >
    </div>
    <!-- In most cases, you don't want to use approvalprompt=force. Specified
    here to facilitate the demo.-->
  </div>

  <div id="email" class="hide"></div>
</body>
</html>

问题1:"Uncaught TypeError: Cannot read property 'load' of undefined“总是失败,

直到我用

<script src="https://apis.google.com/js/client:plusone.js" type="text/javascript"></script>

而不是示例代码:

<script src="https://apis.google.com/js/plusone.js" type="text/javascript"></script>

plusone.jsclient:plusone.js有什么区别?

问题2:为什么代码每页加载两次?

问题3:用户刚登录后就被注销了,如何修复?

错误演示页用于上述操作(所有错误都在后台控制台中)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-07-07 14:46:14

这并不是问题的真正答案,而是一步一步地复制它。

下面是我用来测试的简单html页面(类似于Ray的示例)。为了避免与代码的其他部分交互,我已经尽可能地简化了它:

代码语言:javascript
复制
<html>
<head>
    <script type="text/javascript" 
            src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
</head>
<body>
    <input type="button" id="signOut" value="Sign out"></button>
    <span id="signinButton">
        <span class="g-signin"
            data-accesstype="offline"
            data-callback="signinCallback"
            data-clientid="YOUR_CLIENT_ID_HERE"
            data-cookiepolicy="single_host_origin"
            data-scope="email"
        </span>
    </span>
    <script type="text/javascript">

        $('#signOut').on('click', function() {
            gapi.auth.signOut();
        });

        function signinCallback(authResult) {
            console.log("signinCallback: ", authResult);
        }
        (function() {
            var po = document.createElement('script');
            po.type = 'text/javascript';
            po.async = true;
            po.src = 'https://apis.google.com/js/client:plusone.js';
            var s = document.getElementsByTagName('script')[0];
            s.parentNode.insertBefore(po, s);
        })();
    </script>
</body>
</html>

您必须用自己的google客户端id更新数据客户端,并从授权的javascript源显示此页面。

请注意,这在本地主机上可能不起作用,正如Ian在这篇文章https://plus.google.com/102746521318753162868/posts/Z5Gkro9YXVs的评论中所建议的那样。

首先,登录您的Google帐户:您将在控制台中看到一个成功的回调。

如果单击“注销”,您将在控制台中看到一个带有“user_signed_out”的回调。

到目前一切尚好。

再次登录,并等待1小时,直到令牌过期(这是可怕的测试,因为我不知道如何缩短令牌的生存期)。

一个小时后,单击“注销”按钮:不调用回调。

再次单击“登录”按钮:

  • 使用授权代码和访问令牌,您将获得成功的回调。
  • 紧接着,您将得到一个“user_signed_out”回调。

一旦会话过期,就无法返回到“正常”状态,您总是会得到第二个带有'user_signed_out‘的回调。

实际上,有一种方法可以回到“正常”的状态:取消谷歌仪表板对应用程序的访问。

这对我来说并不是什么问题,因为我使用Google+只是为了登录--使用一次授权代码将用户输入到我的应用程序中,而且我也没有使用来自客户端的访问令牌。

但这阻止了自动登录的工作,因为用户立即被认为是“签署”从谷歌的角度。

票数 2
EN

Stack Overflow用户

发布于 2014-07-07 13:22:19

Q1: client:plusone.js只是告诉加载程序自动加载"client“模块。它基本上是自动执行gapi.load("client"),只是它已经在一次下载中为您打包了。你也可以反过来做,plusone:client.js!

Q2:不确定,这可能是一些JS的怪癖。通常,尝试让您的代码能够处理多个回调,如果状态发生变化,您可能会得到另一个回调(例如,用户从他们的google帐户登录)。

Q3:我在测试页面上没有看到--我已经签好了,并且仍然在刷新时登录!检查您是否在浏览器中阻止第三方cookie或类似的功能?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24608395

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档