首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在表单提交时,通过php文件获取CSRF并将值传递给请求

在表单提交时,通过php文件获取CSRF并将值传递给请求
EN

Stack Overflow用户
提问于 2015-05-18 23:21:34
回答 2查看 1.2K关注 0票数 0

我将赏金这个问题与50分,当合格。

我有一个向上投票系统,类似于这里的投票方式。

当用户通过<form>投票时,我希望submit首先点击' get -csrf.php‘来获得一个CSRF密钥,然后将该值传递给请求。

我如何才能做到这一点?

jQuery代码:

代码语言:javascript
复制
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中,我有返回所需密钥的语句:

代码语言:javascript
复制
if (!isset($_SESSION['csrf'])) {
    $_SESSION['csrf'] = substr( md5(rand()), 0, 7);
}

return $_SESSION['csrf'];

因此,当用户单击submit时,我希望通过我的jQuery代码获取CSRF,然后将其发送到请求并在那里处理它。

EN

回答 2

Stack Overflow用户

发布于 2015-05-18 23:34:31

我建议您这样做的方法是,在将表单传递给用户时,首先将令牌放在隐藏的输入字段中。

代码语言:javascript
复制
<? if (!isset($_SESSION['csrf'])) { ?>
    <input type="hidden" name="csrf-token" value="<?= $_SESSION['csrf'] ?>">
<? } ?>

如果在您的情况下这不是一个可行的解决方案,您可以简单地链接请求。

代码语言:javascript
复制
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编码的字符串,因此您只需将其添加到字符串的末尾:

代码语言:javascript
复制
function ajaxSubmit_votetopicform(token){
   var votetopicform = jQuery(this).serialize();
   votetopicform += "&csrftoken=" + token; //token is passed as parameter to this fn

   ....
}

因此,完整的JavaScript代码将如下所示:

代码语言: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
        }
    });
}
票数 2
EN

Stack Overflow用户

发布于 2015-05-19 00:22:00

对于表单提交,GNi33的答案是一个很好的解决方案,对于这样的用例,我推荐他的答案。我提出的解决方案也适用于表单;但是,它更适用于非表单提交。其思想是在HTTP请求报头中包含CSRF令牌。

代码语言:javascript
复制
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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30307051

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档