我需要使用弹出窗口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
答案 0 :(得分:3)
您无法从任何域访问csrftoken cookie,而是生成它的域。因此,您必须在生成时读取csrftoken,如果要从扩展中使用它,请将其保存。
在我的情况下,当令牌不存在时,它没有导致任何错误,但是一旦我登录服务器,csrftoken被设置,并且无法从任何其他域检索它,获得任何未在同一域中生成的请求都会出现403错误。
要修复它,首先,我必须在登录时从域中读取cookie并将其保存到chrome存储。首先,我需要适当的权限(注意,我使用background / background.js你可以切换到popup / popup.js,如果需要的话)
...,
"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之前检查主机名。
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,每次加载页面时都会从存储中读取令牌。
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') },
...
}