Javascript chrome.identity.launchwebauthflow对于特定用户失败

Javascript chrome.identity.launchwebauthflow对于特定用户失败,javascript,google-chrome-extension,oauth-2.0,Javascript,Google Chrome Extension,Oauth 2.0,我已经研究这个问题很长时间了,但没有成功。希望有人能对此有所启发 我正在开发一个Google Chrome扩展(浏览器操作),其中身份验证/授权在Google之外进行(Chrome.identity.launchwebauthflow,并将interactive设置为true)。我们已经成功地为一些用户(但不是所有用户)提供了身份验证/授权流程。以下是有趣的结果: 用户A单击扩展图标,单击授权按钮,成功获取身份验证代码,将其交换为访问令牌,并可以继续使用应用程序 用户B单击扩展图标,单击授权按钮

我已经研究这个问题很长时间了,但没有成功。希望有人能对此有所启发

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

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

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


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

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

    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;
    
    });
    

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

    这个操作应该是创建一个新窗口并关注它。按照ChromeUI惯例,这应该会关闭扩展弹出窗口,从而完全破坏该页面的JavaScript上下文。将不再有任何可调用的回调

    这解释了为什么“检查弹出窗口”有帮助-这可以防止在焦点丢失时关闭弹出窗口。在这个调试案例之外

    这是一种行为,因此您可能没有在开发机器上看到它。但是惯例是明确的——任何焦点的丢失都会破坏弹出页面

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


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

    从哪里调用
    launchWebAuthFlow
    ?弹出代码?从弹出窗口的javascript中调用launchwebauthflow(当您单击扩展的图标时,弹出窗口出现)。测试用户使用的是相同的操作系统,但我很感激从后台脚本中得到的关于调用的反馈。我试试看。谢谢这也可能是一种竞争条件-弹出窗口关闭后JS上下文被破坏的速度有多快。对于它不工作的用户,他们会看到以下错误:响应标识时出错。launchWebAuthFlow:错误:尝试使用断开连接的端口对象听起来像是计时问题?我使用的是一个后台脚本,其中调用了launchwebauthflow,但我没有定义持久性标志。因为同样的原因,您不能
    sendResponse
    :弹出窗口已关闭,不再存在。没什么可发送的。但对某些用户来说,它工作正常吗?launchwebauthflow打开web视图时,弹出窗口未关闭。web视图将关闭,弹出窗口将更新为您现在经过身份验证和授权时应该显示的内容。
    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;
    
    });