Google帐户关联操作

时间:2017-06-01 15:28:39

标签: ios iphone google-oauth google-oauth2 actions-on-google

根据here所述的文档,我将帐户链接设置为隐式授权,并发现在使用浏览器/操作控制台进行测试时以及使用适用于Android的Google Home应用程序时效果很好。不幸的是,在应用程序的iphone版本中,用户auth大部分时间都会挂起。来自谷歌支持的操作的反馈是,问题是谷歌登录流程是在单独的浏览器选项卡(窗口)中实现的。在iphone上你不能在SfariViewController中打开2个窗口,因此他们正在重写第一页的地址而无法完成登录流程。这是已知问题,他们不打算改变这一点。解决方案是在一个浏览器窗口中实现登录流程。我不清楚如何执行此操作,并且正在寻找某人在您设置的授权网址后面共享代码,这些代码在iphone上始终如一。以下是我正在使用的核心:

.html片段:

<!DOCTYPE html>
<html>
<head>
  <title>Authorization Page</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="google-signin-client_id" content="948762963734-2kbegoe3i9ieqc6vjmabh0rqqkmxxxxx.apps.googleusercontent.com">
  <!-- <meta name="google-signin-ux_mode" content="redirect"> INCLUDING THIS META TAG BREAKS THE AUTH FLOW -->
  <script src="js/googleAuth.js"></script>
  <script src="https://apis.google.com/js/platform.js" async defer></script>
  <link rel="stylesheet" href="css/googleAuth.css">   
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">  
</head>
<body>
<header class="bgimg-1 w3-display-container w3-grayscale-min" id="loginScreen">
  <div class="w3-display-topleft w3-padding-xxlarge w3-text-yellow" style="top:5px"> 
    <span class="w3-text-white">Google Sign In</span><br>
    <span class="w3-large">Sign in with your Google account</span><br><br>
    <div class="g-signin2" data-onsuccess="onSignIn"></div><br><br>        
  </div>   
</header>
</body>
</html>

.js代码段:

function onSignIn(googleUser) {
  var profile = googleUser.getBasicProfile();
  var id = profile.getId()
  var name = profile.getName()
  var email = profile.getEmail()
  var token = googleUser.getAuthResponse().id_token;
  var client_id = getQueryVariable('client_id')
  // vital-code-16xxx1 is the project ID of the google app
  var redirect_uri = 'https://oauth-redirect.googleusercontent.com/r/vital-code-16xxx1'
  var state = getQueryVariable('state')
  var response_type = getQueryVariable('response_type')

  // store the user's name, ID and access token and then sign out
  storeOwnerID (email, name, id, token, function() {
    // sign out
    var auth2 = gapi.auth2.getAuthInstance();
    auth2.signOut().then(function () {
      console.log('signed out')
    });
    // if this page was loaded by Actions On Google, redirect to complete authorization flow
    typeof redirect_uri != 'undefined' ? window.location = redirectURL : void 0    
  }) 
}

function getQueryVariable(variable) {
  var query = window.location.search.substring(1);
  var vars = query.split('&');
  for (var i = 0; i < vars.length; i++) {
    var pair = vars[i].split('=');
    if (decodeURIComponent(pair[0]) == variable) {
      return decodeURIComponent(pair[1]);
    }
  }
  console.log('Query variable %s not found', variable);
}

2 个答案:

答案 0 :(得分:1)

@dana您是否尝试过添加元标记?

<meta name="google-signin-ux_mode" content="redirect">

答案 1 :(得分:1)

在Google支持和帮助的帮助下工程,现在已经解决了:

  1. 如上所述,我必须包含此元标记:<meta name="google-signin-ux_mode" content="redirect">
  2. 我需要在项目的授权重定向URI中使用https://my-auth-endpoint.com/。仅在授权的javascript起源中使用它是不够的。另一个关键的事情是包括尾部斜线,我原本没有它,没有它就无法工作。
  3. 以下是一个简单的代码基础,您可以使用该基础为Google帐户关联操作获取授权终结点的工作版本:

    html的:

    <!DOCTYPE html>
    <html>
    <head>
      <title>Authorization Page</title>
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <meta name="google-signin-client_id" content="948762963734-2kbegoe3i9ieqc6vjmabh0rqqkmxxxxx.apps.googleusercontent.com">
      <meta name="google-signin-ux_mode" content="redirect">
      <script src="js/googleAuth.js"></script>
      <script src="https://apis.google.com/js/platform.js" async defer></script>
      <link rel="stylesheet" href="css/googleAuth.css">   
      <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">  
      <script>
        sessionStorage['jsonData'] == null ? storeQueryVariables() : void 0
      </script>
    </head>
    <body>
    <header class="bgimg-1 w3-display-container w3-grayscale-min" id="loginScreen">
      <div class="w3-display-topleft w3-padding-xxlarge w3-text-yellow" style="top:5px"> 
        <span class="w3-text-white">Google Sign In</span><br>
        <span class="w3-large">Sign in with your Google account</span><br><br>
        <div class="g-signin2" data-onsuccess="onSignIn"></div><br><br>        
      </div>   
    </header>
    </body>
    </html>
    

    的.js:

    // Retrieve user data, store to DynamoDB and complete the redirect process to finish account linking
    function onSignIn(googleUser) {
      let profile = googleUser.getBasicProfile(),
          id = profile.getId(),
          name = profile.getName(),
          email = profile.getEmail(),
          token = googleUser.getAuthResponse().id_token,
          redirect_uri = 'https://oauth-redirect.googleusercontent.com/r/vital-code-16xxxx',
          jsonData = JSON.parse(sessionStorage['jsonData']),
          redirectURL = redirect_uri + '#access_token=' + token + '&token_type=bearer&state=' + jsonData.state
    
      // store the user's name, ID and access token
      storeUserData(email, name, id, token, function() {
        // sign out of google for this app
        let auth2 = gapi.auth2.getAuthInstance();
        auth2.signOut()
        // if this page was loaded by Actions On Google, redirect to complete authorization flow
        typeof redirect_uri != 'undefined' ? window.location = redirectURL : void 0    
      })   
    }
    
    // Store the user data to db
    function storeUserData (email, name, id, token, callback) {
      // removed for simplicity
    }
    
    // Store URI query variable 'state' to browser cache
    function storeQueryVariables() {
      let qvar = {
        'state': getQueryVariable('state')
      }
      storeLocally(qvar)
    }
    
    // Get any variable from incoming URI
    function getQueryVariable(variable) {
      var query = window.location.search.substring(1);
      var vars = query.split('&');
      for (var i = 0; i < vars.length; i++) {
          var pair = vars[i].split('=');
          if (decodeURIComponent(pair[0]) == variable) {
              return decodeURIComponent(pair[1]);
          }
      }
      console.log('Query variable %s not found', variable);
    }
    
    // Store JSON object input to local browser cache 
    function storeLocally (jsonData) {
      if (typeof(Storage) !== 'undefined') {
        sessionStorage['jsonData'] = JSON.stringify(jsonData)
      } else {
        console.log('Problem: local web storage not available')
      }
    }