HariHaraSudhan
HariHaraSudhan

Reputation: 1360

Send cookies with ajax call from chrome extension content script

I'm making a chrome extension for a site which provides api to check if user is signed in or not. The api is for a GET request. So when i'm, not singed in it gives.

{ status: "ok", authenticated: false}

When i'm signed in it gives me

{status : "ok", authenticated: true, id: 123}

This works fine on browser, chrome extensions like Postman and advanced Rest Client. But when i use it in my chrome extension background it always says i'm not a authenticated user. I figured out that the ajax call i make does not send cookies for the domain, but the chrome extension like Postman or Advanced REST client do send cookies along with XHR request.

Any idea how can i make ajax to send cookies along with it.

here is my ajax call from chrome extension

$.ajax({
    method:"GET",
    //  xhrFields: {
       //   withCredentials: true
       // },
       // crossDomain: true,
        url:"http://test-staging.herokuapp.com/user/details",
        success: function(result){
          if(result.status=="ok"){
            alert(JSON.stringify(result));
        cb(result.authenticated);
      }
    },
    error: function(err){
      alert("unable to authenticate user "+JSON.stringify(err))
    }
  })

UPDATE 1:

I'm able to get the domain cookies details from the background script. Now i'm looking how i can send the cookies with the ajax call?

Upvotes: 7

Views: 4408

Answers (2)

Brock Lumbard
Brock Lumbard

Reputation: 23

This is an old question, but what did it for me had to do with setting a couple flags on my cookies.

According to this blog post: https://www.gmass.co/blog/send-cookie-cross-origin-xmlhttprequest-chrome-extension/

You need to have the samesite: None flag set for this to work. This seems kind of obvious, but wasn't mentioned on most other resources for some reason. In addition, if you want samesite = None, you also need the Secure; flag on the set-cookie: response header so that Chrome will actually listen to it.

For me, and likely for you, this means messing around in your API to have those flags set correctly. For me it even meant I had to make HTTPS work on my localhost server I was developing on, so that chrome would trust me that the cookie was secure. In addition, you need credentials: 'include' as the earlier poster said.

For anyone using flask, this looked like:

app.config['SESSION_COOKIE_SAMESITE'] = "None"
app.config['SESSION_COOKIE_SECURE'] = True 

plus debugging with Https (export FLASK_RUN_CERT=adhoc) on the command line.

This is a complex one that took me a long time, but the blog post linked above was a huge help.

Upvotes: 0

Vitaly Kuznetsov
Vitaly Kuznetsov

Reputation: 1763

If the content script is injected into a page with an origin (protocol, host and port combination) different from the API origin:

  • Cookies could be blocked by the third-party cookie blocking feature.
    Check if it is enabled: chrome://settings/content/cookies.
    Background scripts are not affected by it (as of Chrome 81).
  • Either set withCredentials: true (credentials: 'include' for fetch)
    or add the origin into the permissions section of manifest.json.
    To receive the response, correct CORS headers are required in either case.

Prefer moving API calls into a background script and passing data to the content script with sendMessage to circumvent the third-party cookie blocking, CORB and CORS restrictions. If you choose to do so, add the API origin into the permissions section of manifest.json.

Upvotes: 4

Related Questions