• 解决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);
        }

    解决Yii2给数据库表添加字段后对应模型无法识别到该属性的原因

    数据库表的结构被缓存了

    执行:

    //清理所有表结构缓存数据
    Yii::$app->db->getSchema()->refresh();
  • 相关阅读:
    php源码学习——开篇
    springMvc入门一
    spring 整合 servlet
    java jar包下载地址
    java spring学习
    Servlet 学习
    JRE_HOME environment variable is not defined correctly This environment variableis needed to run this program
    java JBDC操作
    Java 自定义异常
    JAVA的日期类DATE
  • 原文地址:https://www.cnblogs.com/dcb3688/p/4607960.html
Copyright © 2020-2023  润新知