Search code examples
javascriptgoogle-chrome-extensionfetch-api

Chrome extension popup: fetch call in incognito mode


(1) I'm creating an extension that works with a website that requires a user log in.

(2) I'm trying to detect if the user is logged in or not, from the extension's popup.

I can tell if the user is logged in or not by making a fetch call to specific URL, let's say http://www.example.com/account, and what happens is:

  • If the account is logged IN, the fetch call is redirected to http://www.example.com/account/data.

  • If the account is logged OUT, the fetch call is redirected to http://www.example.com/login.

The problem is:

I do the fetch call from the extension's content script and it works just fine, but, when I do it from inside the extension's popup, there comes two scenarios:

(1) If I'm logging into the website in a normal window, the fetch call works just fine, it detects that I'm logging in and redirects me to http://www.example.com/account/data.

(2) But, if I'm NOT logging into the website in a normal window and instead logging into it in an incognito window, it does NOT detect my login and it always redirects the fetch call to the http://www.example.com/login page!


I was thinking maybe it has something to do with the website's cookies, so, I tried to get the cookies, using the chrome.cookies API, and set them to the extension's popup, but, this didn't work!

Here is how I was trying to do it:

popup.js

chrome.cookies.getAll({
    domain: 'example.com'
}, function (cookies) {

    cookies.forEach(function (cookie, i) {
        // tried to set it this way, it didn't work: 
        chrome.cookies.set(cookie, function (savedCookie) {});

        // tried to set it to the `document.cookie`, as suggested here: 
        // https://stackoverflow.com/a/59620840/7607751
        // but, this didn't work either: 
        document.cookie = `${cookie.name}=${cookie.value}; `;
    });

    onAfterCookiesHandle();
});


function onAfterCookiesHandle() {
    console.log('document.cookie:', document.cookie);

    fetch(`https://www.example.com/account/`, {
        method: 'GET',
        credentials: 'include',

    }).then(function (response) {
        console.log('response:', response);
        if (response.url === `https://www.example.com/account/data`) {
            console.log('You are logged in, yay!');
        } else {
            console.log('You are logged out, oh no!');
        }

    }).catch(function (error) {
        console.error("HTTP fetch error:", error);
    });
}

PS. I'm enabling the extension to work with the incognito mode (from the extension's settings), and in my manifest.json file I have the key: "incognito": "spanning".

What am I doing wrong here? and how can I get this to work in the incognito mode ?


Solution

  • I fixed it by changing the manifest's incognito key to be split.

    This made me drop the idea of changing the cookies for the popup at all, because the popup in this split mode will be running in the same browser process along with its incognito window, while in the spanning mode the regular and the incognito windows were sharing the same memory cookie store!

    I guess this was the reason for mixing the cookies lookup and the popup were searching for the website's cookies in the regular window's world instead of the incognito window world.

    As per the Chrome extensions's documentation:

    Spanning mode

    The default mode is spanning, which means that the extension will run in a single shared process. Any events or messages from an incognito tab will be sent to the shared process, with an incognito flag indicating where it came from. Because incognito tabs cannot use this shared process, an extension using the spanning incognito mode will not be able to load pages from its extension package into the main frame of an incognito tab.

    Split mode

    The split mode means that all pages in an incognito window will run in their own incognito process. If the extension contains a background page, that will also run in the incognito process. This incognito process runs along side the regular process, but has a separate memory-only cookie store. Each process sees events and messages only from its own context (for example, the incognito process will see only incognito tab updates). The processes are unable to communicate with each other.