在沙盒iframe环境中使用google javascript api

Ben*_*tra 5 html javascript iframe google-api google-api-js-client

我有一个使用google javascript API的HTML5应用.我最近发现这个应用程序需要在iframe沙盒环境中运行.我知道它似乎试图解决沙盒环境的目标; 但是iframe仍然允许一些功能(参见下面的约束),这让我觉得有一些希望.

我在验证过程中遇到问题:加载后,google javascript api会在原始页面上添加一个iFrame(在我的情况下已经是iframe)并使用postMessage机制在windows之间进行通信.我想使用google api进行OAuth2.0身份验证过程以及查询API.

这是一个复制案例; 我使用的是谷歌提供的authSample.html页面的简化版本.

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8' />
    <title>original auth page</title>
</head>
<body>
    <button id="authorize-button">Authorize</button>
    <div id="content">Not authentified</div>
    <script type="text/javascript">
        var clientId = '<use yours>';
        var apiKey = '<use yours>';
        var scopes = 'https://www.googleapis.com/auth/analytics.readonly';
        var authorizeButton = document.getElementById('authorize-button');
        var resultDiv = document.getElementById('content');
        function handleClientLoad() {
            gapi.client.setApiKey(apiKey);
            authorizeButton.onclick = handleAuthClick;
        }

        function handleAuthResult(authResult) {
            if (authResult && !authResult.error) {
                makeApiCall();
            } else {
                resultDiv.innerHTML = "handleAuthResult Failed";
            }
        }

        function handleAuthClick(event) {
            gapi.auth.authorize({ client_id: clientId, scope: scopes, immediate: false }, handleAuthResult);
            return false;
        }

        function makeApiCall() {
            gapi.client.load('analytics', 'v3', function () {
                resultDiv.innerHTML = "api call successful";
            });
        }
    </script>
    <script src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

包含的页面将由最终用户使用,如下所示:

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8' />
    <title>iframed page</title>
</head>
<body>
    <iframe id="8D681BA3DED5" width="400px" height="400px" 
            frameborder="0" sandbox="allow-scripts allow-forms allow-same-origin ms-allow-popups allow-popups" marginheight="0" marginwidth="0" 
            name="MyTest" src="https://localhost:4000/AuthSample.html"></iframe>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

显然,您必须在服务器authSample.html url替换iframe的实际src后执行此页面.

如果您在不同的浏览器上运行它,您会注意到失败的不同行为.我试图利用弹出窗口被允许的事实,但似乎浏览器已经实现了不同的事实,即打开的窗口也应该在沙盒环境中打开.

我想避免编写自己的web服务进行身份验证.此外,我相信用户使用常用的Google网页(使用url accounts.google.com)更安全地输入凭据.如果您有想法,可能适用于最近的浏览器,请随时提交.

谢谢

Ben*_*tra 1

我找到了一个解决方案,\n基本思想是在弹出窗口中执行身份验证流程,该弹出窗口不会继承沙箱跨源安全限制。事实上,沙箱具有以下属性sandbox=\xe2\x80\x9dallow-scriptsallow-formsallow-same-originms-allow-popupsallow-popups\xe2\x80\x9d

\n\n

我写了一篇小博文详细解释了解决方案。

\n\n

编辑(2016 年 9 月):

\n\n

Keluro,我们发布了一个开源代码示例来利用登录技术。它更多地用于连接到 Azure AD/Office 365,但使用dialogApi的客户端和弹出窗口作为后备可以重复使用。

\n