牛骨文教育服务平台(让学习变的简单)
博文笔记

yii2发送异步请求中的小问题,有效处理csrf验证

创建时间:2015-02-02 投稿人: 浏览次数:3454

最近在使用yii2,打算做一个通用的后台系统,实现用户登录和后台基本操作:登录操作采用系统自带的identify组件;后台界面采用bootstrap处理,模板采用网上的后台模板页,不过该模板bootstrap版本过低,改成v3版;界面如下:



界面是响应式的,功能菜单可以自由定制,只要把链接定义写到后台首页即可,十分方便,扩展性强,省了不少麻烦;

说说遇到的问题;比如在做消息回复的时候【如下:ajax操作post】,异步操作表单,发送post请求,后台会报错http400:Bad Request;网上也有解决方案,原因是yii2表单在post后会验证csrf参数,防止跨站csrf伪造攻击!



网友的解决方案是:在当前控制器下增加 public $enableCsrfValidation = false;那么问题来了,该控制器下其他操作中的普通表单post提交,csrf验证就失效了,这样操作安全性就降低了,怎么解决呢?


我的解决方案是:安全第一,山跨不过去,那就绕过去!不去改动 $enableCsrfValidation属性,直接改良我们的视图表单,

如原来的表单代码为:


   <form name="form">
                             <input name="fid" type="hidden" value="<?=Yii::$app->user->getId()?>"/>
                               <input name="tid" type="hidden" value="<?=$msg->name->id?>"/>
                              <input type="hidden" name="title" value="<?=$msg->title?>"/>
                               <div class="form-group">
                                  <textarea name="content" class="form-control" id="content" cols="30" placeholder="至少输入10个字符" rows="4"></textarea>
                            </div>
                               <input name="reply" type="hidden" value="1"/>
                               <a class="btn btn-success" id="replytohim" cansend="1" href="javascript:void(0);">回复</a>
                           </form>

修改后的表单为:

 <?php $form=ActiveForm::begin(
                                [
                                    "action"=>["admin/msg/reply"],
                                   "method"=>"post",
                                    "options"=>["name"=>"form"]
                                ]
                            )?>
                                <?=$form->field($model,"fid")->hiddenInput(["value"=>Yii::$app->user->getId()])?>
                                <?=$form->field($model,"tid")->hiddenInput(["value"=>$msg->name->id])?>
                                <?=$form->field($model,"title")->hiddenInput(["value"=>$msg->title])?>
                                <div class="form-group">
                                    <?=$form->field($model,"content")->textarea(["rows"=>30,"placeholder"=>"至少输入10个字符","rows"=>4])?>
                                </div>
                                <?=$form->field($model,"reply")->hiddenInput(["value"=>"1"])?>
                            <a class="btn btn-success" id="replytohim" cansend="1" href="javascript:void(0);">回复</a>
                            <?php ActiveForm::end()?>


这样的话表单就会生成<input type="hidden" name="_csrf" > 然后异步提交过去就可以顺利通过验证了,也不会影响其他普通表单的操作!


  /**
     * @reply 在当前消息下回复对方
     */

    public function  actionReply(){
        $arr=array();
        if(Yii::$app->request->isAjax){
            $msg=Yii::$app->request->post("Msg");
            $obj=new Msg();
            $obj->fid=$msg["fid"];
            $obj->tid=$msg["tid"];
            $obj->title=$msg["title"];
            $obj->content=$msg["content"];
            $obj->reply=$msg["reply"];
            $obj->send_time=time();
            $obj->save();
            $arr["status"]=1;

        }else{
            $arr["status"]=0;
        }
        echo json_encode($arr);
    }



声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。