4

我有一個書籤Firefox /鉻WebExtension(使用標準popup,contentbackground腳本)。我的api服務器有一個/ login路由,它返回一個JSON Web Token,並且該Web應用程序將其存儲在本地存儲中。我完全可以控制擴展,api和網絡應用程序。如何將本地存儲身份驗證令牌從我的網站共享到我的WebExtension?

這樣做的赤腳方法是讓用戶通過彈出窗口登錄並將身份驗證令牌保存在background.js中以保存到WebExtension的本地存儲中。但我真的只想要求用戶在我的網站上進行身份驗證,並且同樣的身份驗證也適用於該擴展。

有沒有辦法共享認證令牌?我看到Pocket和許多其他人這樣做,但我不知道如何。

+0

最簡單的方法很可能是發送身份驗證令牌作爲cookie。 – Forivin

+2

您可以使用內容腳本閱讀網站的localStorage,然後通過消息將該令牌複製到背景頁面localStorage中。 – wOxxOm

+0

@ wOxxOm好的方法,不知道內容腳本可以訪問外部網站的本地存儲。事實上,我認爲本地存儲比這更安全。這將需要mysite.com打開一個新標籤,但這對我的用例來說是一個值得的折衷。這是相關的:https://stackoverflow.com/questions/3937000/chrome-extension-accessing-localstorage-in-content-script。 – user

回答

5

您可以將令牌存儲爲cookie。 Cookie的工作方式類似於localStorage,但額外的是,默認情況下,Cookie也會包裝到服務器的每個HTTP請求中。訣竅來了。 Chrome擴展程序可以訪問HTTP請求,並使用webRequest API。因此它可以查看請求頭並知道你的cookies。將該Web令牌作爲Cookie使其可用於擴展。

但仍然需要等待用戶打開您的網站才能讓HTTP請求流動並準備好被偷窺,對嗎?不是真的。您可以直接從擴展中發出ajax請求。

下面就來說明整個事情將如何工作:

清單:

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

背景頁:

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

我應該指出,有一個更清潔的方式做到這一點,但由於CSP - 內容安全策略,它目前無法使用。正如wOxxOm在評論中提到的那樣,在後臺頁面內的iframe中打開網站應該可以正常工作,並將CSP列入白名單。這種方法也可以避免提示用戶輸入憑據,並且會更乾淨。不幸的是它的not currently working

編輯:

對不起,我錯了我的最後一個要求:在打開外部頁面的I幀被阻擋在後臺頁面。要將其顯示在後臺頁面(或針對該事件的彈出窗口)中,只需將CSP列入白名單,如下所示。

除了在iframe中打開頁面的業務之外,您還需要與之通信。

清單:

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

背景:

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

的應該在使用本window.postMessage API

下面就來舉例說明這一切是如何應該團結起來做網頁:

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

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

編輯:

此外,爲了具有在iframe網站顯示,確保X-frame-options響應頭沒有被設置爲一個阻塞值。您可以將其刪除,也可以將其設置爲非阻止值,或者將該擴展程序的網址白名單。

+0

好方法。在我的特殊情況下,我已經在本地存儲中擁有令牌,而不是cookie。我可以開始使用cookie,但我認爲經過一些修改,您的答案也可以用於本地存儲。這隻取決於我後臺的iframe是否允許訪問本地存儲。 – user

+1

@user iframes允許訪問localStorage,但前提是iframe沒有指定沙箱屬性。如果添加了該屬性,請確保添加了以下2個值: