如何在chrome扩展开发中访问popup的cookie?

时间:2015-03-10 00:21:24

标签: javascript django google-chrome cookies google-chrome-extension

我需要使用弹出窗口j将一些数据发布到django服务器。由于csrf,我应该在cookie中使用csrftoken发布数据,我如何获取cookie中的值。我尝试了以下不起作用的方法:

document.cookie

chrome.cookies.get({url: "chrome-extension://igmgfjnbghncmhbobdpjblokohejackc", name: "csrftoken"}, function(cookie){})

请求信息:

Request Method:POST
Status Code:403 FORBIDDEN
Request Headersview source
Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:zh-CN,zh;q=0.8
Connection:keep-alive
Content-Length:3
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Cookie:csrftoken=V6OTh2NdwnomqLbkfh24qRwT8C0kESIV
Host:127.0.0.1:8000
Origin:chrome-extension://igmgfjnbghncmhbobdpjblokohejackc
User-Agent:Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X)      AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d    Safari/600.1.4
X-CSRFToken:null

2 个答案:

答案 0 :(得分:3)

您无法从任何域访问csrftoken cookie,而是生成它的域。因此,您必须在生成时读取csrftoken,如果要从扩展中使用它,请将其保存。

在我的情况下,当令牌不存在时,它没有导致任何错误,但是一旦我登录服务器,csrftoken被设置,并且无法从任何其他域检索它,获得任何未在同一域中生成的请求都会出现403错误。

要修复它,首先,我必须在登录时从域中读取cookie并将其保存到chrome存储。首先,我需要适当的权限(注意,我使用background / background.js你可以切换到popup / popup.js,如果需要的话

的manifest.json

...,
"background": {
    "scripts": ["jquery-1.11.1.min.js","background.js"],
    "persistent": false
  },
"permissions": ["tabs", "<all_urls>", "storage", "webNavigation"],
"content_scripts":[
 {
  "matches":["yourDomain"],
  "js": ["jquery-1.11.1.min.js", "readCSRFToken.js"]
 }],...

现在,这个小脚本将读取我们需要的cookie,如果它存在并将其发送到我们的扩展。如果要确保使用正确的CSRF令牌,可以在发送cookie之前检查主机名。

readCSRFToken.js

function getCookie(name) {
     var cookieValue = null;
     if (document.cookie && document.cookie != '') {
         var cookies = document.cookie.split(';');
         for (var i = 0; i < cookies.length; i++) {
             var cookie = jQuery.trim(cookies[i]);
         if (cookie.substring(0, name.length + 1) == (name + '=')) {
             cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
             break;
         }
     }
 }
 return cookieValue;
}
csrftoken = getCookie("csrftoken");
if ( csrftoken ){
    chrome.runtime.sendMessage({action:"setCsrfToken", csrftoken:csrftoken}, function(){});
}

在扩展代码中,我们添加了一个侦听器,当注入的代码发送csrf令牌时,它会将csrf令牌保存在chrome存储中。 还有一个webNavigation.onComplete,每次加载页面时都会从存储中读取令牌。

background.js

csrftoken = null;
chrome.webNavigation.onCompleted.addListener(function(details) {
    if ( details.frameId == 0 ){
         chrome.storage.sync.get(["csrftoken"], function(storage){
            csrftoken = storage.csrftoken;
        });}
    }
);
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    switch ( request.action ){
        case "setCsrfToken":{
            chrome.storage.sync.set({'csrftoken': request.csrftoken}, function() {});
        }
        break;
    }
});

最后,我们存储了一个csrftoken变量,我们应该可以使用它来设置“X-CSRFToken”标头,以便在扩展中使用时允许我们的AJAX请求正常工作。

   ...
   var headers = {}
   if ( csrftoken ) headers["X-CSRFToken"] = csrftoken;

    $.ajax({                                                                                                                                                                                                                             
     dataType: 'json',                                                                                                                                                                                                               
     headers: headers,
     ...
    });

答案 1 :(得分:1)

我假设您已按照以下步骤操作:https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/#how-to-use-it

我不熟悉popup.js,但由于它是一个jquery插件,这应该适合你。将csrftoken放入请求标头的ajax请求:

$.ajax({                                                                                                                                                                                                                             
 dataType: 'json',                                                                                                                                                                                                               
 headers: {"X-CSRFToken": $.cookie('csrftoken') },
 ...
}