特定用户

时间:2016-02-29 21:17:18

标签: javascript google-chrome-extension oauth-2.0

我一直在研究这个问题很长一段时间,并没有成功。希望有人可以对此有所了解!

我正在开发Google Chrome扩展程序(浏览器操作),其中身份验证/授权在Google之外完成(chrome.identity.launchwebauthflow interactive设置为true)。我们已经成功使用了一些用户的身份验证/授权流程,但并非所有用户都成功。以下是有趣的结果:

  1. 用户A点击扩展图标,点击授权按钮,成功获取授权代码,交换访问权限,然后继续使用该应用程序。
  2. 用户B点击扩展图标,点击授权按钮,弹出窗口关闭。它在交换授权代码以访问令牌之前失败。
  3. 用户B右键单击扩展图标,选择Inspect弹出窗口,单击授权按钮,成功获取授权码,交换它以访问令牌,然后继续使用该应用程序。
  4. 用户A使用网络以安全模式启动设备。用户A单击扩展图标,单击授权按钮,扩展弹出窗口关闭。它在交换授权代码以访问令牌之前失败。
  5. 用户A使用网络以安全模式启动设备。用户A打开一个标签并加载扩展名的网址(chrome-extension://pathofextension)。用户单击“授权”按钮,成功获取授权代码,交换访问令牌,然后继续使用该应用程序。
  6. 扩展程序转换为打包的应用程序。用户A和B打开应用程序,单击授权按钮,成功获取授权代码,交换它以访问令牌,并可继续使用该应用程序。
  7. 我们认为这是一个客户问题,但我们都使用相同的Chrome版本。返回授权代码时,什么会导致扩展程序的弹出窗口关闭?我们无法保持开发人员控制台处于打开状态,以查看是否出现任何错误,因为当开发人员控制台打开时,它可以正常工我们正在使用$.ajaxSetup({ cache:false })来确保对ajax请求禁用缓存。

    这是chrome.identity.launchwebauthflow调用的片段(最初从弹出窗口调用):

    chrome.identity.launchWebAuthFlow({url:url,interactive:true},function(response) {
        console.log('OAuth Response: '+response);
        if (response) {
            var authCode = encodeURIComponent(response.substring(response.indexOf('=')+1));
            console.log('Auth Code: '+authCode);
            userAuthorization(authCode);
        } else {
            authorizeButton();
        }
    });
    

    尝试应用代码在后的解决方案后编辑的代码:

    弹出脚本现在调用后台脚本:

    chrome.runtime.sendMessage({type:'authorize',url:url},function(response) {
        console.log(chrome.runtime.lastError);
        console.log(response);
        if (response && response.authCode) {
            userAuthorization(response.authCode);
        } else {
            authorizeButton();
        }
    });
    

    后台脚本响应弹出脚本。

    chrome.runtime.onMessage.addListener(function(message,sender,sendResponse) {
    
        if (message.type == 'authorize') {
    
            var url = message.url,
                authCode;
    
        chrome.identity.launchWebAuthFlow({url:url,interactive:true},function(response) {
                console.log('OAuth Response: '+response);
                if (response) {
                    authCode = encodeURIComponent(response.substring(response.indexOf('=')+1));
                    console.log('Auth Code: '+authCode);
                }
                sendResponse({authCode:authCode});
            }); 
    
        }
    
        return true;
    
    });
    

1 个答案:

答案 0 :(得分:2)

从扩展程序弹出窗口调用launchWebAuthFlow是一个非常糟糕的主意。

此操作应该创建一个新窗口并专注于它。根据Chrome用户界面约定,这应该关闭扩展程序弹出窗口 - 并使用它完全销毁该页面的JavaScript上下文。将不再有回拨电话。

这解释了为什么"检查弹出窗口"帮助 - 这可以防止在焦点丢失时关闭弹出窗口。 There is no override for this mechanism在此调试案例之外。

此弹出解雇行为may subtly differ by OS,因此您可能没有在开发计算机上看到它。但惯例很清楚 - 任何失去焦点都应该破坏弹出页面。

扩展程序中唯一不会被意外关闭的真正持久的部分是后台脚本 - 您应该在哪里处理chrome.identity授权。从请求它的弹出代码发送消息。

更新:请注意,由于同样的原因,您无法向sendMessage返回响应 - 弹出窗口不再存在。您的逻辑应该是每次弹出窗口打开时尝试使用interactive: false检索令牌 - 如果失败,请求后台启动交互流程(并且期望关闭,因此没有sendResponse