|
本帖最后由 ^淡如清风 于 2014-5-19 17:06 编辑
首先我们看文档:http://codeigniter.org.cn/user_guide/libraries/security.html
最后几行讲解到:
跨站请求伪造(Cross-site request forgery,CSRF)
打开你的 application/config/config.php 文件,进行如下设置,即可启用 csrf 保护:
PHP复制代码 $config['csrf_protection'] = TRUE; 复制代码
如果你使用 表单辅助函数, form_open() 函数将会自动地在你的表单中插入一个隐藏的csrf字段.
这是文档所介绍的方法:
必须使用 form_open() 来生成表单隐藏域,来实现防止跨站请求。
于是查看了下 form_open() 的源码
PHP复制代码 /**
* Form Declaration
*
* Creates the opening portion of the form.
*
* @access public
* @param string the URI segments of the form destination
* @param array a key/value pair of attributes
* @param array a key/value pair hidden data
* @return string
*/
if ( ! function_exists('form_open'))
{
function form_open ($action = '', $attributes = '', $hidden = array())
{
$CI =& get_instance ();
if ($attributes == '')
{
$attributes = 'method="post"';
}
// If an action is not a full URL then turn it into one
if ($action && strpos($action, '://') === FALSE)
{
$action = $CI->config->site_url($action);
}
// If no action is provided then set to the current url
$action OR $action = $CI->config->site_url($CI->uri->uri_string());
$form = '<form action="'.$action.'"';
$form .= _attributes_to_string ($attributes, TRUE);
$form .= '>';
// Add CSRF field if enabled, but leave it out for GET requests and requests to external websites
if ($CI->config->item('csrf_protection') === TRUE AND ! (strpos($action, $CI->config->base_url()) === FALSE OR strpos($form, 'method="get"')))
{
$hidden[$CI->security->get_csrf_token_name()] = $CI->security->get_csrf_hash();
}
if (is_array($hidden) AND count($hidden) > 0)
{
$form .= sprintf("<div style=\"display:none\">%s</div>", form_hidden ($hidden));
}
return $form;
}
} 复制代码
发现,生成表单隐藏域重点是这几行
PHP复制代码 // Add CSRF field if enabled, but leave it out for GET requests and requests to external websites
if ($CI->config->item('csrf_protection') === TRUE AND ! (strpos($action, $CI->config->base_url()) === FALSE OR strpos($form, 'method="get"')))
{
$hidden[$CI->security->get_csrf_token_name()] = $CI->security->get_csrf_hash();
} 复制代码
于是不难发现,我们可以直接在模板中使用,方法如下
PHP复制代码 <?php if ($this->config->item('csrf_protection') === TRUE) { ?>
<input type="hidden" name="<?php echo $this->security->get_csrf_token_name(); ?>" value="<?php echo $this->security->get_csrf_hash(); ?>" />
<?php } ?> 复制代码
或是在控制器中把隐藏域先生成,然后在模板中直接输出
控制器:
PHP复制代码 $data['token'] = '';
if ($this->config->item('csrf_protection') === TRUE) {
$data['token'] = '<input type="hidden" name="' . $this->security->get_csrf_token_name() . '" value="' . $this->security->get_csrf_hash() . '" />';
}
$this->load->view('reg_index', $data); 复制代码
模板直接输出变量即可:
注意:只能应用于post请求哦
|
|