我将赏金这个问题与50分,当合格。
我有一个向上投票系统,类似于这里的投票方式。
当用户通过<form>投票时,我希望submit首先点击' get -csrf.php‘来获得一个CSRF密钥,然后将该值传递给请求。
我如何才能做到这一点?
jQuery代码:
jQuery('.votetopicform').submit(ajaxSubmit_votetopicform);
function ajaxSubmit_votetopicform(){
var votetopicform = jQuery(this).serialize();
jQuery.ajax({
type:"POST",
url: SiteParameters.site_url+"/wp-admin/admin-ajax.php",
data: votetopicform,
success:function(data){
jQuery(".feedback").html(data); // empty div to show returned data
}
});
return false;
}在get-csrf.php中,我有返回所需密钥的语句:
if (!isset($_SESSION['csrf'])) {
$_SESSION['csrf'] = substr( md5(rand()), 0, 7);
}
return $_SESSION['csrf'];因此,当用户单击submit时,我希望通过我的jQuery代码获取CSRF,然后将其发送到请求并在那里处理它。
发布于 2015-05-18 23:34:31
我建议您这样做的方法是,在将表单传递给用户时,首先将令牌放在隐藏的输入字段中。
<? if (!isset($_SESSION['csrf'])) { ?>
<input type="hidden" name="csrf-token" value="<?= $_SESSION['csrf'] ?>">
<? } ?>如果在您的情况下这不是一个可行的解决方案,您可以简单地链接请求。
jQuery('.votetopicform').submit(ajaxSubmit_requestcsrftoken);
function ajaxSubmit_requestcsrftoken(){
jQuery.ajax({
type:"POST",
url: SiteParameters.site_url+"/get-csrf.php",
success:function(data){
ajaxSubmit_votetopicform(data);
}
});
}不是在提交表单时直接调用ajaxSubmit_votetopicform,而是先调用一个请求csrf-token的函数。服务器将令牌返回给所述函数,该函数调用发送实际提交的函数,并将返回的令牌作为参数传递给它。
在ajaxSubmit_votetopicform函数中,您现在只需要将返回的令牌添加到请求中提交的数据中。
由于$.serialize()返回的是url编码的字符串,因此您只需将其添加到字符串的末尾:
function ajaxSubmit_votetopicform(token){
var votetopicform = jQuery(this).serialize();
votetopicform += "&csrftoken=" + token; //token is passed as parameter to this fn
....
}因此,完整的JavaScript代码将如下所示:
//set the submit - event handler to a function, that requests the token first
jQuery('.votetopicform').submit(ajaxSubmit_requestcsrftoken);
function ajaxSubmit_requestcsrftoken(){
jQuery.ajax({
type:"POST",
url: SiteParameters.site_url+"/get-csrf.php",
success:function(data){
// after succesfully requesting the CSRF - token, call the function
// that should submit the actual form data to your server and pass the token as parameter to it
// this way you are chaining one request after the other
ajaxSubmit_votetopicform(data);
}
});
return false; //prevent the form from submitting
}
function ajaxSubmit_votetopicform(token){
var votetopicform = jQuery(this).serialize();
//add the token as additional parameter to be sent to the server
votetopicform += "&csrftoken=" + token;
jQuery.ajax({
type:"POST",
url: SiteParameters.site_url+"/wp-admin/admin-ajax.php",
data: votetopicform,
success:function(data){
jQuery(".feedback").html(data); // empty div to show returned data
}
});
}发布于 2015-05-19 00:22:00
对于表单提交,GNi33的答案是一个很好的解决方案,对于这样的用例,我推荐他的答案。我提出的解决方案也适用于表单;但是,它更适用于非表单提交。其思想是在HTTP请求报头中包含CSRF令牌。
jQuery('.votetopicform').submit(ajaxSubmit_votetopicform);
function ajaxSubmit_votetopicform() {
var votetopicform = jQuery(this).serialize();
// chain AJAX requests
jQuery.ajax({
type: "GET",
url: SiteParameters.site_url + "/wp-admin/get-csrf.php"
}).then(function(token) {
jQuery.ajax({
type: "POST",
url: SiteParameters.site_url + "/wp-admin/admin-ajax.php",
data: votetopicform,
headers: {
"_RequestToken": token
}
});
});
return false;
}https://stackoverflow.com/questions/30307051
复制相似问题