4

Ich habe ein Lesezeichen Firefox/Chrome WebExtension (mit den Standard-popup, content und background Skripte). Meine API-Server haben eine/login-Route, die einen JSON-Web-Token zurückgibt, und die Web-App speichert diesen in seinem lokalen Speicher. Ich habe die volle Kontrolle über die Erweiterung, API und Web-Apps.Wie kann ich ein lokales Speicher-Authentifizierungs-Token von meiner Site an meine WebExtension weitergeben?

Der barfuß Weg, dies zu tun, ist, Benutzer über das Popup einzuloggen und das Authentifizierungs-Token in der background.js im lokalen Speicher der WebExtension zu speichern. Aber ich möchte wirklich nur den Benutzer bitten, auf meiner Site zu authentifizieren und diese selbe Berechtigung auch auf die Erweiterung anwenden zu lassen.

Gibt es eine Möglichkeit, das Authentifizierungs-Token zu teilen? Ich sehe Pocket und viele andere, die das machen, aber ich weiß nicht wie.

+0

Der einfachste Weg wäre wahrscheinlich die Auth-Token als Cookie zu senden. – Forivin

+2

Sie können die localStorage der Site mit einem Inhaltsskript lesen und dann das Token in Ihre Hintergrundseite localStorage per Messaging kopieren. – wOxxOm

+0

@wOxxOm guter Ansatz, wusste nicht, dass das Inhaltsskript auf den lokalen Speicher einer externen Site zugreifen konnte. In der Tat dachte ich, dass der lokale Speicher sicherer ist. Das wird allerdings bedeuten, einen neuen Tab mit mysite.com zu öffnen, aber das ist ein lohnender Kompromiss für meinen Anwendungsfall. Dies ist verwandt: https://stackoverflow.com/questions/3937000/chrome-extension-accessing-localstorage-in-content-script. – user

Antwort

5

Sie könnten das Token als Cookie speichern. Cookies funktionieren wie localStorage, aber mit dem Extra, dass sie auch standardmäßig in jede HTTP-Anfrage an den Server eingebunden sind. Und hier kommt der Trick. Chrome Extension kann über die API webRequest auf HTTP-Anfragen zugreifen. So kann es einen Blick in die Anfrage Header und weiß Ihre Cookies. Wenn Sie dieses Web-Token als Cookie verwenden, wird es für die Erweiterung verfügbar.

Aber immer noch müssen Sie warten, bis Ihre Website vom Benutzer geöffnet wird, um HTTP-Anfragen fließen zu lassen und bereit zu sein, zu sehen, richtig? Nicht wirklich. Sie können eine Ajax-Anfrage direkt über die Nebenstelle stellen.

Hier ist zu zeigen, wie das Ganze funktionieren würde:

manifestieren:

"permissions": [ 
      "webRequest", 
      "webRequestBlocking", 
      "*://*.my_site.com/*" 
     ] 

Hintergrund Seite:

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

sollte ich erwähnen, dass es eine sauberere Möglichkeit zu tun Sie es, aber es funktioniert derzeit nicht wegen CSP - Content Secutiry Policiy. Öffnen der Website in einem iframe innerhalb der Hintergrundseite, wie von wOxxOm in Kommentaren erwähnt, sollte funktionieren, mit zusätzlichen CSP Whitelisting der Website. Dieser Ansatz würde auch vermeiden, den Benutzer nach Anmeldeinformationen zu fragen, und wäre sauberer. Leider ist es not currently working

EDIT:

Sorry, ich war falsch über meine letzte Behauptung: dass iframes Öffnen externe Seiten im Hintergrund Seiten gesperrt sind. Um es auf der Hintergrundseite (oder in einem Popup-Fenster) anzuzeigen, müssen Sie einfach eine weiße Liste für CSP erstellen - siehe unten.

Abgesehen von der Aufgabe, die Seite in einem iframe zu öffnen, müssen Sie damit kommunizieren.Das sollte

ist mit dem window.postMessage API getan wird hier beispielhaft, wie alles zusammen kommen sollte:

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"} 

Hintergrund:

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") 

Des Webseite:

window.addEventListener("message", receiveMessage, false); 

function receiveMessage(event) 
{ 
    if(event.origin == "your_extension_id_aeiou12345"); 
    event.source.postMessage(''+localStorage.auth_token, event.origin); 
} 

EDIT:

, auch die Website-Anzeige in einem Iframe zu haben, stellen Sie sicher, dass die X-frame-options Antwort-Header nicht auf einen Sperrwert gesetzt. Sie können es entweder entfernen oder auf einen nicht blockierenden Wert setzen oder die URL der Erweiterung in eine weiße Liste aufnehmen.

+0

Guter Ansatz. In meinem speziellen Fall habe ich das Token bereits im lokalen Speicher anstelle eines Cookies. Ich könnte anfangen, Cookies zu verwenden, aber ich denke, mit einigen Änderungen kann Ihre Antwort auch für den lokalen Speicher verwendet werden. Das hängt davon ab, ob der Iframe in meinem Hintergrund den Zugriff auf den lokalen Speicher erlaubt. – user

+1

@user Iframes erlauben den Zugriff auf localStorage, aber nur, wenn im iframe kein Sandbox-Attribut angegeben ist. Wenn Sie dieses Attribut hinzufügen, stellen Sie sicher, dass diese 2 Werte hinzugefügt wurden: kundrata

1

Da meine Anforderungen so einfach waren wie „Ich brauche Auth-Token T von der Website W“, hier ist was ich getan habe:

Zuerst speichern ein Cookie auf der Haupt-Website mit den Auth-Token, auch wenn sein bereits in lokaler Speicher.

Auf Popup-Skript, vor dem Rendern, rufen

browser.cookie.get({name: 'https://website-W.com', name: 'auth_token'}) 
.then(function(cookie) { 
    console.log(cookie); // {..., value: "bearer-token-value" } 
    var token = cookie.value; 
    // send message to background script to store cookie globally 
    // continue rendering successfully 
}) 
.catch(function(error) { 
    console.error(error); 
    // handle not logged in 
}) 
Verwandte Themen