现在的位置: 首页 > 编程开发 > Php > 编程开发 > 正文

Yii 防CSRF攻击 Token验证

2015年10月16日 Php, 编程开发 ⁄ 共 253字 ⁄ 字号 暂无评论

在Yii框架中,为了防止csrf攻击,封装了CSRF令牌验证。
只需要在主配置文件中进行简单的配置,就可以实现CSRF的验证。

'components'=>array(
'request'=>array(
// Enable Yii Validate CSRF Token
'enableCsrfValidation' => true,
),
),


将enableCsrfValidation设置为true了之后,使用Yii表单生成页面的时候,如果表单的提交方式为POST,是都会在页面中添加一个隐藏字段


自己写的表单需要手动添加隐藏字段



用户在提交表单的同时,将该字段提交给服务器端,Yii框架会将该有客户端提交过来的隐藏字段和客户端提交过来的Cookie中的YII_CSRF_TOKEN值进行比较。
相同则通过继续执行,不相同则会抛出400异常:"The CSRF token could not be verified."。

上面的方法是将客户端提交过来的值和客户端的Cookie中的值进行比较,并不是最为安全的方法。

目前更为安全的方式,是将客户端提交过来的值和Session中的值进行比较,这就需要重写CHttpRequest类了。具体步骤如下:

1.重写CHttpRequest:
创建一个类HttpRequest继承于CHttpRequest,并将该类存放在 protected/components 下。
重写CHttpRequest的 getCsrfToken() 和 validateCsrfToken($event) 方法。


private $_csrfToken;
//
public function getCsrfToken()
{
if($this->_csrfToken===null)
{
$session = Yii::app()->session;
$csrfToken=$session->itemAt($this->csrfTokenName);
if($csrfToken===null)
{
$csrfToken = sha1(uniqid(mt_rand(),true));
$session->add($this->csrfTokenName, $csrfToken);
}
$this->_csrfToken = $csrfToken;
}

return $this->_csrfToken;
}
//
public function validateCsrfToken($event)
{
if($this->getIsPostRequest())
{
// only validate POST requests
$session=Yii::app()->session;
if($session->contains($this->csrfTokenName) && isset($_POST[$this->csrfTokenName]))
{
$tokenFromSession=$session->itemAt($this->csrfTokenName);
$tokenFromPost=$_POST[$this->csrfTokenName];
$valid=$tokenFromSession===$tokenFromPost;
}
else
$valid=false;
if(!$valid)
throw new CHttpException(400,Yii::t('yii','The CSRF token could not be verified.'));
}
}

2.修改配置文件main.php:

'components' => array(
'request' => array(
'class' => 'application.components.HttpRequest',
'enableCsrfValidation' => true,
),
),

给我留言

您必须 [ 登录 ] 才能发表留言!

×