You could store the token as a cookie. Cookies work like localStorage
, but with the extra that the're also by default wrapped into every HTTP request to the server. And here comes the trick. Chrome Extension can gain access to HTTP requests, with the use of webRequest
API. Thus it can take a peek into the request headers and know your cookies. Having that web token as a cookie makes it available to the extension.
But still you need to wait for your website to be opened by the user, to have HTTP requests flowing and ready to be peeked at, right? Not really. You can make make an ajax request directly from the extension.
Here's to illustrate how the whole thing would work:
manifest:
"permissions": [
"webRequest",
"webRequestBlocking",
"*://*.my_site.com/*"
]
Background page:
function callback (details) {
//
token = func_extract_token_from_headers(details.requestHeaders);
chrome.webRequest.onBeforeSendHeaders.removeListener(callback);
return {cancel: false} // set to true to prevent the request
// from reaching the server
}
chrome.webRequest.onBeforeSendHeaders.addListener (callback,
{urls: ["http://www.my_site.com/*", "https://www.my_site.com/*"]},
["blocking", "requestHeaders"]);
var xurl = "https://www.my_site.com/";
var xhr = new XMLHttpRequest();
xhr.open("GET", xurl, true);
xhr.send();
I should mention that there's a cleaner way to do it, but it currently does not work due to CSP--Content Secutiry Policiy. Opening the website in an iframe inside the background page, as mentioned by wOxxOm in comments, should work, with added CSP whitelisting of the website. This approach would also avoid prompting the user for credentials, and would be cleaner. Unfortunately it's not currently working
EDIT:
Sorry, I was wrong about my last claim: that iframes opening external pages are blocked in background pages. To display it in the background page(or popup for that matter), simply whitelist for CSP -- shown below.
Apart from the business of opening the page in an iframe, you need to communicate with it. That should be done using the window.postMessage API
Here's to exemplify how it all should come together:
Manifest:
// Whitelist your website
"content_security_policy": "script-src 'self' https://my_site.com/; object-src 'self'"
// Have the background declared as html
"background": { "page": "background.html"}
Background:
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{
if(event.origin == "https://my_site.com"); // you may want to check the
// origin to be your site
chrome.storage.storage.local.set({'auth_token': event.data}); // the token
}
iframe = document.createElement('iframe');
iframe.src = "https://my_site.com/";
// Have a div ready to place iframe in
document.getElementById('div').appendChild(iframe);
iframe.contentWindow.postMessage("give_token", "https://my_site.com")
The web page:
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{
if(event.origin == "your_extension_id_aeiou12345");
event.source.postMessage(''+localStorage.auth_token, event.origin);
}
EDIT:
Also, to have the website display in an iframe, make sure the X-frame-options
response header is not set to a blocking value. You can either remove it, or set it to a non-blocking value, or white-list the url of the extension.