简体   繁体   English

为什么带有“ immediate:false”的gapi.auth.authorize不关闭弹出窗口并触发回调?

[英]Why gapi.auth.authorize with “immediate: false” doesn't close popup and fire callback?

I'm working on some chrome-extension. 我正在开发一些扩展名。 The Google Developer Console is configured and using gapi eventually works, but I've got problem with, let's say, UX. Google开发人员控制台已配置完毕,并且最终可以使用gapi进行工作,但是,例如UX,我遇到了问题。

So here is scenario I'm trying to acheive: 所以这是我要实现的方案:

  1. Try to authenticate with Google Chrome logged in user. 尝试使用Google Chrome登录用户进行身份验证。
  2. If fail, try to authenticate via gapi.auth.authorize with immediate: true. 如果失败,请尝试通过gapi.auth.authorize进行即时身份验证:true。
  3. If fail, try to authenticate via gapi.auth.authorize with immediate: false. 如果失败,请尝试通过gapi.auth.authorize进行即时身份验证:false。

And this kind of works. 而这种作品。 I get the popup which asks for permission, I click Accept, but then popus goes blank, title is set to "Connecting..." (doesn't close) and callback function is never fired. 我得到要求许可的弹出窗口,单击“接受”,但是弹出窗口变为空白,标题设置为“ Connecting ...”(未关闭),并且永远不会触发回调函数。

I know access is granted because when I click accept and reload the page, it can authorize using immediate:true and my extension works perfectly. 我知道访问是被授予的,因为当我单击接受并重新加载页面时,它可以使用Instant:true进行授权,并且我的扩展程序可以正常工作。

I check few issues, topics and questions asking different queries in google searching for the answer and I found this sollutions: 我在Google搜索了几个问题,主题和问题并询问了不同的查询以寻找答案,然后发现了以下解决方案:

  1. setTimeout(checkAuth, 1) - tried, no success. setTimeout(checkAuth,1)-尝试过,没有成功。
  2. I deduced that immediate:false cannot be called right after immediate:true, so I give it a try and tried to authenticate with immediate:false as first. 我推论不能在即时:真之后立即调用即时:假,因此我尝试一下,尝试首先使用即时:假进行身份验证。 Same results. 结果相同。
  3. I tried adding gapi.auth.init, and checkingAuth in it's callback (also using setTimeout). 我尝试添加gapi.auth.init,并在其回调中检查Author(也使用setTimeout)。

So here is bit of code (background.js). 因此,这里是一些代码(background.js)。 Sorry it looks like spaghetti, I'm beginner in JS. 抱歉,看起来像意大利面条,我是JS的初学者。

function respond(interactive, sendResponse) {
    xhrWithAuth('GET',
        'https://www.googleapis.com/gmail/v1/users/me/profile',
        interactive, // false
        onUserMailFetched, sendResponse);

    function xhrWithAuth(method, url, interactive, callback, sendResponse) {
        var access_token;
        var retry = true;

        getToken();
        // 1. trying to use Chrome user
        function getToken() {
            chrome.identity.getAuthToken({
                interactive: interactive
            }, function (token) {
                if (chrome.runtime.lastError) {
                // 2. here lastError is User is not signed in. Calling onUserMailFetched
                    callback(chrome.runtime.lastError, null, null, sendResponse);
                }
                access_token = token;
                requestStart();
            });
        }
        // I guess not important in topic
        function requestStart() {
            var xhr = new XMLHttpRequest();
            xhr.open(method, url);
            xhr.setRequestHeader('Authorization', 'Bearer ' + access_token);
            xhr.onload = requestComplete;
            xhr.send();
        }
        // I guess not important in topic
        function requestComplete() {
            if (this.status == 401 && retry) {
                retry = false;
                chrome.identity.removeCachedAuthToken({
                        token: access_token
                    },
                    checkAuth_neverCalled);
            } else {
                callback(null, this.status, this.response, sendResponse);
            }
        }
        // I guess not important in topic
        function checkAuth_neverCalled() {
            console.log("checking auth when getAuthToken fails");
            gapi.auth.authorize({
                client_id: OAUTH2_CLIENT_ID,
                scope: OAUTH2_SCOPES,
                immediate: false
            }, handleAuthResult);

            // Handle the result of a gapi.auth.authorize() call.
            function handleAuthResult(authResult) {
                console.log("authenticated: ", authResult);
                if (authResult) {
                    // do something with data
                } else {
                    consoel.log("failed");
                }
            }
        }
    }

    // This is important part.
    function onUserMailFetched(error, status, response, sendResponse) {
        if (!error && status == 200) {
            // do something with data
        } else {
         // 3. as we have error at first call, we checkAuth with immediate = true
            setTimeout(function () {
                checkAuthWhenNotLogged(sendResponse, true);
            }, 10);
        }
    }
    // This is important part.
    function checkAuthWhenNotLogged(sendResponse, immediateVal) {
        gapi.auth.authorize({
            client_id: OAUTH2_CLIENT_ID,
            scope: OAUTH2_SCOPES,
            immediate: immediateVal
        }, handleAuthResult);

        // Handle the result of a gapi.auth.authorize() call.
        // 5. But this function is never called again (when called with false).
        function handleAuthResult(authResult) {
            if (authResult) {
            // 4. and this is called when checkAuth with true fail. We call checkAuth (itself) with false.
                if (authResult.error == "immediate_failed") {
                    gapi.auth.init(function () {
                        setTimeout(function () {
                            checkAuthWhenNotLogged(sendResponse, false);
                        }, 10);
                    });
                } else {
                // yay, we are authneticated and can call gmail service
                    gapi.client.load('gmail', 'v1', function () {
                        var request = gapi.client.gmail.users.getProfile({
                            'userId': 'me'
                        });
                        request.execute(function (profile) {
                            // do something with data
                        });
                    });
                }
            } else {
                console.log("failed");
            }
        }
    }
}

Any hint, link or solution will be apreciated. 任何提示,链接或解决方案都将受到重视。

Ok, here is what I did to make OAuth2 work. 好的,这是使OAuth2正常工作的方法。

Scenario looks like: 场景如下:

  1. Try to authenticate with Google Chrome logged in user. 尝试使用Google Chrome登录用户进行身份验证。
  2. If fail, try to authenticate via gapi.auth.authorize with immediate: true. 如果失败,请尝试通过gapi.auth.authorize进行即时身份验证:true。
  3. If fail, try to use chrome.identity.launchWebAuthFlow 如果失败,请尝试使用chrome.identity.launchWebAuthFlow

First of all I need to explain why launchWebAuthFlow wasn't working earlier. 首先,我需要解释为什么launchWebAuthFlow不能更早地工作。 As I mention, I configured the Google Developers Console and created key and client id as for Chrome Application. 如前所述,我配置了Google Developers Console,并为Chrome应用程序创建了密钥和客户端ID。 This was wrong for launchWebAuthFlow. 这对于launchWebAuthFlow是错误的。 It should be Web Application with configured redirect URL. 它应该是具有配置的重定向URL的Web应用程序。

In chrome extension here is how you can get redirect url: var redirectURL = chrome.identity.getRedirectURL("suffix"); 在chrome扩展程序中,这是获取重定向URL的方法:var redirectURL = chrome.identity.getRedirectURL(“ suffix”); It will create something like this: https://{appId}.chromiumapp.org/ 它将创建如下内容:https:// {appId} .chromiumapp.org /

You need to set this as redirect link in your Client ID configuration. 您需要在客户端ID配置中将此设置为重定向链接。 In my case I had to change used Client ID in js code. 就我而言,我必须在js代码中更改已使用的客户端ID。

Here is code that works for me: 这是对我有用的代码:

(...)
var redirectURL = chrome.identity.getRedirectURL();
var options = {
    'interactive': true,
    url: 'https://accounts.google.com/o/oauth2/auth?' +
        'scope=profile email' +
        '&response_type=token' +
        '&client_id=' + OAUTH2_CLIENT_ID_WEB +
        '&redirect_uri=' + redirectURL
}
chrome.identity.launchWebAuthFlow(options, function (redirectUri1) {
    if (chrome.runtime.lastError) {
        console.log(chrome.runtime.lastError);
    } else {
        // redirectUri is a link with access_token param inside, we need to extract it
        var paramName = "access_token"
        var results = new RegExp(paramName + '=([^&#]*)').exec(redirectUri1);
        if (results == null) {
            console.log("not found");
        } else {
            console.log(results[1] || 0);
            access_token = results[1]; // here we set the token
            requestStart(); // here I launch google api request
        }
    };
});
(...)
function requestStart() {
        // url = 'https://www.googleapis.com/plus/v1/people/me'
        // method = 'GET'
        var xhr = new XMLHttpRequest();
        xhr.open(method, url);
        xhr.setRequestHeader('Authorization', 'Bearer ' + access_token);
        xhr.onload = requestComplete;
        xhr.send();
    }

function requestComplete() {
    if (this.status == 401 && retry) {
        retry = false;
        chrome.identity.removeCachedAuthToken({
                token: access_token
            },
            checkAuth);
    } else {
        callback(this.status, this.response);
    }
}

Hope someone will take advantage of this. 希望有人会利用这一点。 I know I spent way too much time on this. 我知道我花了太多时间在此上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 带立即数的gapi.auth.authorize:true不起作用 - gapi.auth.authorize with immediate: true is not working 在node-webkit应用程序上通过Google登录时,不会调用gapi.auth.authorize回调 - gapi.auth.authorize callback doesn't get called when doing sign-in via Google on node-webkit app 检测用户在使用gapi.auth.authorize时是否关闭弹出窗口 - Detect if user closes popup when using gapi.auth.authorize gapi.auth.authorize:TypeError:cv(...)为null - gapi.auth.authorize: TypeError: cv(…) is null gapi.auth.authorize:TypeError:_.Uu不是函数 - gapi.auth.authorize: TypeError: _.Uu is not a function 使用gapi.auth.authorize时访问被拒绝错误 - Access Denied Error when using gapi.auth.authorize 如何将login_hint传递给gapi.auth.authorize? - How do I pass login_hint to gapi.auth.authorize? Google OAuth gapi.auth.authorize X-Frame-Options:SAMEORIGIN - Google OAuth gapi.auth.authorize X-Frame-Options: SAMEORIGIN 对于 javascript 调用 api “gapi.auth.authorize” 的 google 分析没有得到执行。 - For javascript the call to api “gapi.auth.authorize” for google analytics not getting executed. authorize()方法不会为CustomAuthorizer触发 - authorize() method doesn't fire for CustomAuthorizer
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM