专栏首页IT码农解决Yii2 启用_csrf验证后POST数据仍提示“您提交的数据无法验证”

解决Yii2 启用_csrf验证后POST数据仍提示“您提交的数据无法验证”

一 CSRF 概念

CSRF(Cross-site request forgery跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。

Yii2 中的CSRF配置

Yii2 默认是启用CSRF令牌验证

配置在main.php中:

'components' => [
        'request' => [
            // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
            'enableCookieValidation' => true,
            'cookieValidationKey' => 'cookvalid',
        ],
      …………

若要取消CSRF验证有两种方法

1. 在要取消的控制器中添加:

public $enableCsrfValidation = false;

2. 在配置中取消enableCookieValidation的验证

'components' => [
        'request' => [
            // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
            'enableCookieValidation' => false,
            'cookieValidationKey' => 'cookvalid',
        ],
    …………

二 启用CSRF的 POST验证

当启用了csrf后, 所有表单POST提交的数据就会进行验证,在表单中添加CSRF有两种方法

1. 使用Yii挂件生成html

这样会自动生成带有隐藏表单的_csrf

<?php
                    $form = ActiveForm::begin([
                                'id' => 'login-form',
                    ]);
                    ?>
                    <input type="hidden" name="jfinal_token" value="${jfinal_token }" />
                    <div class="form-group">
                        <label for="j_username" class="t">用户名:</label> 
                        <?php echo Html::input('type', 'LoginForm[username]', $model->username, ['class' => 'form-control x319 in', 'placeholder' => 'Username', 'autocomplete' => 'off']); ?>
                    </div>
                    <div class="form-group">

                        <label for="j_password" class="t">密 码:</label> 
                        <?php echo Html::input('password', 'LoginForm[password]', $model->password, ['class' => 'form-control x319 in', 'placeholder' => 'Password']); ?>
                    </div>
                   
                    <?php ActiveForm::end(); ?>

2. 手动添加_csrf

在form表单中手动添加隐藏表单,也适用于ajax的手动添加_csrf

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

三 提交POST提示“您提交的数据无法验证”

使用原生or Yii挂件生成html带有_csrf 表单提交仍然提示“您提交的数据无法验证”

表单html如下:

<div class="login_form">
    <form id="login-form" action="/default/login" method="post">
    <input type="hidden" name="_csrf" value="bDV6RjFCS0RURzcwCAwKNC5AIyIDdy19BkAOF38YGSkLGCI2UgcEMQ==">
    <div class="form-group">
        <label for="j_username" class="t">用户名:</label> 
         <input type="type" class="form-control x319 in" name="LoginForm[username]" placeholder="Username" autocomplete="off">               
    </div>
    <div class="form-group">
    <label for="j_password" class="t">密 码:</label> 
          <input type="password" class="form-control x319 in" name="LoginForm[password]" placeholder="Password">        
    </div>
     </form>     
</div>

_csrf 是Yii自动生成,不存在字符串不匹配

后来找到问题:

render的时候使用了exit, 应使用return

*注: render 时也不能用echo 或 die()

解决办法:

return $this->render('action',['t'=>$t,'text'=>$text]);

封装render

return $this->display([
            't' => $t,
            'text' => $text,
        ]);



 /**
     *  render页面
     * @param array  当$i为array模版为$this->action,数据源为$i
     * 当$i为string,模版为$i,数据源为$param
     */
    protected function display($i = array(), $param = array()) {
        $data = array();
        if (is_string($i)) {
            $tpl = $i;
            $data = $param;
        } else {
            $data = $i;
          $tpl = $this->action->id;
        }

       return $this->render(strtolower($tpl), $data);
    }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Laravel5.3之Container源码解析

    说明:本文主要学习Laravel中Container的源码,主要学习Container的绑定和解析过程,和解析过程中的依赖解决。分享自己的研究心得,希望对别人有...

    botkenni
  • yii2种ajax提交数据时校验出问题

    记一次yii2种ajax提交数据时校验出问题,直接跳过addError,报错语不现实‘不存在!’

    botkenni
  • 深入理解PHP原理之变量(Variables inside PHP)

    或许你知道,或许你不知道,PHP是一个弱类型,动态的脚本语言。所谓弱类型,就是说PHP并不严格验证变量类型(严格来讲,PHP是一个中强类型语言,这部分内容会在以...

    botkenni
  • vue render jsx 事件绑定 条件渲染 slots 插槽

    yangdongnan
  • (第二弹代码实现)iSA:DNA甲基化新的分析方法

    接着上一篇 iSA:DNA甲基化新的分析方法(part 1) 下载并且安装好了软件工具+数据后,进行下一步分析了。

    liu_ll
  • Web修改密码功能

    MD5加密方法参考: http://www.bootcdn.cn/blueimp-md5/ https://github.com/blueimp/JavaS...

    麦克劳林
  • Windows server 2003AD升级到Windows server 2012 R2的操作过程

    1首先准备Windows server 2003 ,Windows server 2003 R2,Windows server 2008 R2,Windows ...

    月缺
  • 常用开源框架中设计模式使用分析-责任链设计模式

    说起来设计模式,大家应该都耳熟能详,下面就带大家看下开源框架框架中是如何应用这些经典设计模式的。

    加多
  • Layui form 表单(常用)

    layui-form div.layui-form-item label.layui-form-label div.layui-input-block

    用户5760343
  • 一个完整的Django入门指南(二)

    第三部分 Introduction        In this tutorial, we are going to dive deep into two f...

    zhang_derek

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动