Google + 登录按钮被阻止的框架

Posted

技术标签:

【中文标题】Google + 登录按钮被阻止的框架【英文标题】:Google + SignIn Button Blocked Frame 【发布时间】:2013-07-12 01:28:03 【问题描述】:

我一直在尝试使用 Google + SignIn 构建一种 Hello World 项目。我按照https://developers.google.com/+/web/signin/ 的教程进行操作,我的(摘录)代码是:

...
<script>
        function signinCallback(authResult) 
        //location.reload();
        //var x = 0
        //while(x=0)
            if (authResult['access_token']) 
                // Successfully authorized
                 // Hide the sign-in button now that the user is authorized, for example:
                 document.getElementById('signinButton').setAttribute('style', 'display: none');
                //document.getElementById("secret").innerhtml = ("<a href="secret.html"><p>Non-Conspicuous Link to Super Secret Page</p></a>");
                //alert("IT WORKED");
                document.getElementById("secret").innerHTML=("Non-Conspicuous Link to Super Secret Page");
                document.getElementById("game").innerHTML=("Non-Conspicuous Link to Super Secret Game Page");
                document.getElementById('refresh').setAttribute('style', 'display: none');
                //alert("Please Refresh");
                  else if (authResult['error']) 
                 // There was an error.
                 // Possible error codes:
                 //   "access_denied" - User denied access to your app
                 //   "immediate_failed" - Could not automatically log in the user
                 console.log('AuthERROR: ' + authResult['error']);
                //alert("ERROR: A team of poorly trained robots has been dispatched to handle the situation. If they arive, tell them '" + authResult['error'] + "'");
              
            
        </script>
...
<span id="signinButton">
        <span 
            class="g-signin"
            data-callback="signinCallback"
            data-clientid="CLIENT ID"
            data-cookiepolicy="single_host_origin"
            data-requestvisibleactions="http://schemas.google.com/AddActivity"
            data-scope="https://www.googleapis.com/auth/plus.login"
            data-
            data-theme="light">
        </span>
...
<a href="secret.html"><p id="secret"></p></a>
...

当我在 Google Chrome(版本 29.0.1547.18 dev-m)中运行代码时,我收到此错误:

Blocked a frame with origin "https://accounts.google.com" from accessing a frame with origin "https://apis.google.com". Protocols, domains, and ports must match.

我的 signinCallback 函数中的代码在页面首次加载时被调用,但在使用按钮登录时不会运行。代码在页面重新加载之前不会执行。

但是,这个问题在 Firefox 中不会发生,所以它似乎是一个孤立于 Chrome 的错误。我还没有测试任何其他浏览器。

有没有办法解决这个问题?

谢谢!

【问题讨论】:

当您说在页面加载时调用回调时,您的意思是使用 access_token 调用它还是使用 authResult['error'] == 'immediate_failed' 调用它? @BrettJ 应该使用 authResult['error'] = 'immediate_failed' 调用回调,并且还应该使用成功登录(更改了access_token?) 该函数也应该被调用。但是,Chrome 中没有。 仔细检查您在 Google API 控制台中指定的来源,以确保它们与您提供页面的位置相匹配。这些必须在协议、域和端口号上匹配。 @BrettJ 我将页面托管在本地服务器上,是否可以在 API 控制台中将其指定为来源 'localhost'? 是的,您可以列出 http://localhost(或者如果适用,也可以在特定端口上),但是当您投入生产时,您会希望删除它,因为如果您的客户端 ID 被盗,其他人可以通过从 localhost 执行操作来使用您的配额。 【参考方案1】:

我正在调整 java 混合服务器端流程 quick-start app,即使使用 https,也会出现“帧阻塞”错误。我发现错误是由这段 javascript 客户端代码(在 onSignInCallback 函数内)触发的:

for (var field in authResult) 
  $('#authResult').append(' ' + field + ': ' +
      authResult[field] + '<br/>');

上面的代码是快速启动应用程序的一部分,仅用于教育目的。枚举或获取 authResult 对象中的某个字段时会发生错误。删除上面的代码(或用 try-catch 块包围它)解决了这个问题。

【讨论】:

我遇到了类似的问题,因为我将 authResult 作为 data 传递给 jQuery XHR。在内部,jQuery 正在迭代导致上述错误的数据属性。很棒的发现! 宾果游戏。响应包含对子窗口的引用,当被同源策略阻止时,父窗口无法访问该子窗口。我在尝试序列化 oauth 响应以将其保存在本地存储中时遇到了这个问题。只要我跳过名为“g-oauth-window”的属性,我就能得到我需要的东西。【参考方案2】:

事实证明,我的按钮在没有刷新的情况下无法进行身份验证的原因是因为我忘记关闭服务器上的 &lt;script&gt;,即使它已在我的问题中的代码中关闭。

对于该错误,您似乎可以忽略它(感谢@Ismael Toé)。

【讨论】:

以上是关于Google + 登录按钮被阻止的框架的主要内容,如果未能解决你的问题,请参考以下文章

iOS sdk 中的 Google Plus 登录按钮框架

Express.js - 跨域请求被阻止

Google 选择器身份验证弹出窗口被阻止

iOS:谷歌登录错误,您的应用被阻止

Google+ 登录将用户注销

如何在使用 Google 登录按钮时不将 Google 帐户添加到 Android 手机