Codeigniter(CSRF)jQuery ajax问题

10

我这里有一个问题,当我尝试使用ajax(POST)发布内容时,我一直收到错误提示。我知道这是CSRF导致的问题,我已经尝试了很多方法来寻找解决方案。但是,我希望这里有人能帮助我!

这是我一直收到的错误信息(来自Google Chrome检查器):

*无法加载资源:服务器响应状态为500(内部服务器错误) XHR完成加载:"http://localhost/woho/ajax/images"。*

PHP(控制器)

class Ajax extends CI_Controller {

    function images() {

        echo 'Hello World';

    }

}

JavaScript

var ID = $(".imageWrap:last").attr("id");
var baseurl = "http://localhost/woho/";
var doScroll = 1;
var cct = $.cookie('csrf_cookie_name');

if (location.href == baseurl) {
    $(window).scroll(function(){
        if ($(window).scrollTop() > $('body').height() / 2) {
            if(doScroll == 1) {                   
                $.post(baseurl + 'ajax/images',{'id' : ID, 'csrf_token_name': cct}, function(data) {
                    alert(data);
                    $("#wrapper_content").append(data);
                    ID++;
                });
            }
        }
    });
}

我从 JavaScript 中获取的 CCT 变量给了我正确的令牌或“哈希”,但当 JavaScript 发送 Ajax 请求时,Codeigniter 返回错误消息:

遇到错误 请求的操作不被允许。

我该如何修复这个问题?需要在我的控制器中验证 CSRF 令牌或其他什么吗?

我正在使用 Codeigniter 2.0.3。


顺便说一句,在2.0.3中没有$this->security->get_csrf_token_name();这样的东西。不确定@Alfonso Rubalcava从哪里得到的。 - Jakub
6个回答

11

尝试以下JavaScript代码:

var ID = $(".imageWrap:last").attr("id");
var baseurl = "http://localhost/woho/";
var doScroll = 1;
var cct = $.cookie("<?php echo $this->config->item("csrf_cookie_name"); ?>");

if (location.href == baseurl) {
    $(window).scroll(function(){
        if ($(window).scrollTop() > $('body').height() / 2) {
            if(doScroll == 1) {                   
                $.post(baseurl + 'ajax/images',{'id':ID,'<?php echo $this->security->get_csrf_token_name(); ?>': cct}, function(data) {
                    alert(data);
                    $("#wrapper_content").append(data);
                    ID++;
                });
            }
        }
    });
}

1
天啊,当然我需要使用实际名称而不是变量名。哈哈,谢谢!下一个是隧道视野吗? - Dexty

3
请检查您在/application/config/config.php中的$config['csrf_token_name']值,默认设置为csrf_test_name而不是csrf_token_name。这个决定是为了避免在Javascript中使用PHP代码。
$.ajax({
    url: 'some_url',
    type: 'POST',
    data: {csrf_test_name: $.cookie('csrf_cookie_name')}
});

这段代码运行良好。


1
如果您使用 form_open("/some",'id="some_form"')form_close(),CI 将创建一个隐藏的输入,其中包含 csrf_token_name 及其值。

因此,在您的 AJAX 请求中,您可以通过序列化表单并发送表单来获取表单!

例如:

<script>
var _form = $("#some_form").serializeArray();
$.ajax({
    data: _form,
    type: 'post',
    url: '<?php echo base_url();?>some',
    async: true,
    success: function(output){
        alert(output);
    },
    complete: function(output){},
    fail: function(err){}
});
</script>

跨站请求伪造(CSRF)一直是我的难题,通过这种方法,问题终于得到解决了!


0

可能已经有点晚了,但我找到了完美的解决方案,这算是一种骇客方法,但应该能行。

if (isset($_SERVER["REQUEST_URI"])) 
{
    if(stripos($_SERVER["REQUEST_URI"],'/mypage') === FALSE)
    {
        $config['csrf_protection'] = TRUE;
    }
    else
    {
        $config['csrf_protection'] = FALSE;
    } 
} 
else 
{
    $config['csrf_protection'] = TRUE;
} 

// 在 config.php 文件中 ci 2.*

这篇帖子 中找到了解决方案


0

我曾经遇到过同样的问题,但现在我已经解决了这个问题。

首先,我在header.php中为每个页面创建了csrf_token,代码如下:

$csrf = array(
                'name' => $this->security->get_csrf_token_name(),
                'hash' => $this->security->get_csrf_hash()
        );

<script type="text/javascript">
    var cct = "<?php echo $csrf ['hash']; ?>";
  </script>

在此之后,当我们通过ajax发送特定值时,我们必须像下面的代码一样发送csrf令牌

$.ajax({
    url:"<?php echo APPPATHS.'staff_leave/leaveapproval/getAppliedLeaveDetails'; ?>",
    data:{id:id,status:status,'<?php echo $this->security->get_csrf_token_name(); ?>': cct},
    method:"post",
    dataType:"json",
    success:function(response)
    {
        alert('success');
    }
});

希望这段代码能对你有所帮助,因为它在我的电脑上是可以运行的。


-1

只需按照这个代码:

$.ajax({
    type : 'post',
    url  : 'Your URL',
    data : {
        id: id,
        '<?php echo $this->security->get_csrf_token_name(); ?>' : '<?php echo $this->security->get_csrf_hash(); ?>'
    },
    datatype: 'json',
    success : function(data){}
});

我认为这个答案与其他答案相同,包括被接受的答案。 - M. Prokhorov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,