CI的csrf的使用说明

在application的config中可以开启csrf的设置:

$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_test_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 7200;
$config['csrf_regenerate'] = TRUE;
$config['csrf_exclude_uris'] = array();

如果开启后,会在CI的核心类的构造函数中,进行调用:

// CSRF Protection check
if ($this->_enable_csrf === TRUE && ! is_cli())
{
	$this->security->csrf_verify();
}

而这个:

$this->security->csrf_verify();

会在非post请求中设置cookie。

    /**
	 * CSRF Verify
	 *
	 * @return	CI_Security
	 */
	public function csrf_verify()
	{
		// If it's not a POST request we will set the CSRF cookie
		if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST')
		{
			return $this->csrf_set_cookie();
		}

		// Check if URI has been whitelisted from CSRF checks
		if ($exclude_uris = config_item('csrf_exclude_uris'))
		{
			$uri = load_class('URI', 'core');
			foreach ($exclude_uris as $excluded)
			{
				if (preg_match('#^'.$excluded.'$#i'.(UTF8_ENABLED ? 'u' : ''), $uri->uri_string()))
				{
					return $this;
				}
			}
		}

		// Check CSRF token validity, but don't error on mismatch just yet - we'll want to regenerate
		$valid = isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name])
			&& is_string($_POST[$this->_csrf_token_name]) && is_string($_COOKIE[$this->_csrf_cookie_name])
			&& hash_equals($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]);

		// We kill this since we're done and we don't want to pollute the _POST array
		unset($_POST[$this->_csrf_token_name]);

		// Regenerate on every submission?
		if (config_item('csrf_regenerate'))
		{
			// Nothing should last forever
			unset($_COOKIE[$this->_csrf_cookie_name]);
			$this->_csrf_hash = NULL;
		}

		$this->_csrf_set_hash();
		$this->csrf_set_cookie();

		if ($valid !== TRUE)
		{
			$this->csrf_show_error();
		}

		log_message('info', 'CSRF token verified');
		return $this;
	}

$this->security->csrf_verify();

如果是非post请求,则设置cookie,如果是post请求,则校验post请求核cooke是否正确,即token校验。

使用的是,如果是post请求,请在js代码中的post请求中插入数据:

data['csrf_test_name']=getCookie('csrf_cookie_name');

其中:csrf_test_name和csrf_cookie_name为config中设置的。

也可以这样:

data['csrf_test_name']='security->get_csrf_hash();?>';

或者:

data['security->get_csrf_token_name();?>']='security->get_csrf_hash();?>';

值都是一样的。

getCookie函数的代码为:

        function getCookie(name){
            var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));
            if(arr != null) return unescape(arr[2]); return null;
        }

如果不插入这个,请求返回会报403错误。

在app里面,就不需要做任何验证了,ci已经自动进行了验证,验证完会去掉post请求参数中的csrf的变量。

CodeIgniter 的这个csrf安全会在所有页面中生成csrf的cookie,不管你要不要。

其中config中的这个设置

$config['csrf_exclude_uris'] = array();

是过滤不需要验证的url,cookie还是要生成的。

你可能感兴趣的:(CI,PHP)