Yii2表单提交报错:unable to verify your data submission

  •   
  • 4640
  • PHP
  • 6
  • super_dodo
  • 2016/09/18

Yii2在提交表单的时候遇到"Unable to verify your data submission" 这种情况,是因为Yii2的防止拦截了csrf攻击,你则不能提交的表单。如果你希望当前可以多次重复提交,或者你写的是API接口,可以在当前提交的表单controller中局部关闭csrf,不过需要注意对用户提交的数据进行安全性验证和过滤。


class ApiController  extends Controller{

	public $enableCsrfValidation = false;			//局部关闭

	/**
	 * @return mixed
	 * 活动页面(Lpage)用户提交feedback的信息上来
	 */
	public function actionAdd(){
		$name = Yii::$app->request->post('name');           //名称
		$safe_name = $this->safeClean($name);				//安全过滤
		//TODO
	}


	//对提交上来的数据进行安全验证过滤
	public function safeClean($string){
		$string = trim($string);
		$string = strip_tags($string);
		$string = htmlspecialchars($string);
		$string = str_ireplace('<script>', '', $string);
		$string = str_ireplace('</script>', '', $string);
		$string = str_replace(array ('"', "\\", "'", "/", "..", "../", "./", "//" ), '', $string);
		//......以及其他方面的验证过滤等
		return $string;
	}

}


Web网页访问的时候form表单中会有对应的一个隐藏input:_csrf进行了验证才可以正常进行访问;而非网页访问方式(不通过Web表单)是无法通过csrf验证的。上述可以通过查看源代码发现有一个name=_csrf的hidden.可以在所在控制器设置$enableCsrfValidation=false;

//如果你不是API接口的话,不建议关闭,

public $enableCsrfValidation = false;

Yii2 功能很是强大,组件化编程很高大上,全栈编程很容易,但我觉得日常的开发中还是有很大一部分人会去手写表单之类的,为了配合前端的工作,或者懒得再去学这套堪比一门新语言的组件语法....

Yii2默认是对表单采取 CSRF 验证的,近些年 CSRF 也越来越被人们所在意,它比 XSS 更阴险更精明,有兴趣的可以百度下网络安全编程方面的相关知识,这里就不再累述了。

如果是自己手写的表单,且没有关闭 Yii2 自身的 CSRF 验证的话,就会出现 “Unable to verify your data submission” 的错误提示,而网上大多数都是教你如何关闭 CSRF 验证.

安全编程要贯彻到底,下面教你如何使自己的表单符合 CSRF 验证,下面给出正确的表单写法.

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>FormValidate</title>
</head>
<body>
	<div>
		<form method="post" action="">
			<input type="text" name="name">
			<input type="submit" value="submit">
			<!-- _csrf -->
			<input type="hidden" name="<?php echo \Yii::$app->request->csrfParam; ?>" value="<?php echo \Yii::$app->request->getCsrfToken();?>">
		</form>
	</div>
</body>
</html>

//说明:即在表单中添加一个input hidden元素即可
name : \Yii::$app->request->csrfParam;
value:\Yii::$app->request->getCsrfToken();

输出 request 组件其实就能看到一个公共的成员属性  
public $csrfParam = '_csrf';

相关链接:
从Yii2的Request看其CSRF防范策略

Yii2局部关闭CSRF拦截防范策略(api接口等)

Yii2的CSRF令牌验证以及重写加强安全性