yii2发送异步请求中的小问题,有效处理csrf验证
最近在使用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);
}声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
