qq3737002 2015-06-29 10:44:38 43467次浏览 10条评论 35 18 0

第一种解决办法是关闭Csrf

public function init(){
    $this->enableCsrfValidation = false;
}

第二种解决办法是在form表单中加入隐藏域

<input name="_csrf" type="hidden" id="_csrf" value="<?= Yii::$app->request->csrfToken ?>">

第三种解决办法是在AJAX中加入_csrf字段

var csrfToken = $('meta[name="csrf-token"]').attr("content");
$.ajax({
  type: 'POST',
  url: url,
  data: {_csrf:csrfToken},
  success: success,
  dataType: dataType
});
觉得很赞
  • 评论于 2015-06-30 10:55 举报

    哦哦, 也就是说只要开启了crsf验证的话,就得在前台页面上有一个 类似这样的表单数据提交给后台,YII会进行匹配

    <input type="hidden" value="dWl3LW1IbU0cHA14VHwufCQvTmk9flV1REREZQUwFDomMRpDCTEhYA==" name="_csrf">
    

    能不能说下,Yii这个匹配的过程,Yii::$app->request->csrfToken 这个值存储在哪里的,怎么匹配的?

    3 条回复
    评论于 2015-06-30 11:15 回复

    存储位置

        protected function createCsrfCookie($token)
        {
            $options = $this->csrfCookie;
            $options['name'] = $this->csrfParam;
            $options['value'] = $token;
            return new Cookie($options);
        }
    

    校验方法

        public function validateCsrfToken($token = null)
        {
            $method = $this->getMethod();
            // only validate CSRF token on non-"safe" methods http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1
            if (!$this->enableCsrfValidation || in_array($method, ['GET', 'HEAD', 'OPTIONS'], true)) {
                return true;
            }
    
            $trueToken = $this->loadCsrfToken();
    
            if ($token !== null) {
                return $this->validateCsrfTokenInternal($token, $trueToken);
            } else {
                return $this->validateCsrfTokenInternal($this->getBodyParam($this->csrfParam), $trueToken)
                    || $this->validateCsrfTokenInternal($this->getCsrfTokenFromHeader(), $trueToken);
            }
        }
    
    评论于 2017-06-05 16:00 回复

    如果第二种 如果有很多输入框 那是不是要写很多个隐藏域??累死

    评论于 2017-06-22 18:02 回复

    一个表单一个

    , 觉得很赞
  • 评论于 2016-03-05 09:54 举报

    Yii::$app->request->csrfToken 产生新的cookie csrf,那从前台传到后台它是怎么个验证流程,能跟我讲讲原理么?

  • 评论于 2016-10-16 12:07 举报

    我按照上述操作post 加了csrfToke,ajax还是报400错误

    觉得很赞
  • 评论于 2016-10-17 12:44 举报

    QQ图片20161017124335.png
    需要在header中设置X-CSRF-Token

    3 条回复
    评论于 2016-11-03 16:19 回复

    我也按照你们的方法都试了还是不行 但是我又不想关csrf

    评论于 2016-11-05 15:18 回复

    你确定你写对了

    评论于 2016-11-06 13:50 回复

    一直在用

    觉得很赞
  • 评论于 2017-02-22 15:27 举报

    非常感谢楼主的帖子,我正好遇到这个问题,一直不知道什么原因。看到之后明白了!万分感谢,为了给您点赞回复,专门注册了一个账号!再次表示感谢

  • 评论于 2017-09-07 16:33 举报

    已经试过禁用csrf,但还是报404是为什么呢?

    1 条回复
    评论于 2017-10-12 10:25 回复

    页面未找到 跳转错误了吧

  • 评论于 2017-10-13 16:21 举报

    刚看到楼主的帖子,使用第二种方法,刚开始试是不行的,需要将input标签的name值设置成跟APP的request组件的csrfParam值一样才能起作用

  • 评论于 2017-10-20 10:12 举报

    眼一下......

  • 评论于 2018-08-07 17:34 举报

    很难受,这个问题困扰了很久。第三个方法是最开始用的,但是没起作用,不知道什么原因。
    最终用第一个方法解决了。在控制器里定义 $enableCsrfValidation=false

    1 条回复
    评论于 2018-08-24 16:53 回复

    你可以看看是不是你的配置里修改了 request 组件中的 csrfParam 的名称

  • 评论于 2018-12-13 16:04 举报

    后面两种方法具体实现可参考Yii.js文件

您需要登录后才可以评论。登录 | 立即注册