0

我正在使用Ben Edmunds Ion Auth Library
我对使用csrf_nonce方法的任何函数都有问题 - 它没有通过 post 检查。

我检查了 flashdata 是否已设置(我可以在表单中将其视为隐藏输入 [edit_user 例如]),但是当您提交表单时,flashdata 检查失败。

如果这有什么不同,我将使用数据库进行会话。

代码片段;
控制器

function edit_user($id) {
    $this->data['title'] = "Edit User";

    if (!$this->ion_auth->logged_in() || !$this->ion_auth->is_admin()) {
        redirect('auth', 'refresh');
    } //!$this->ion_auth->logged_in() || !$this->ion_auth->is_admin()

    $user          = $this->ion_auth->user($id)->row();
    $groups        = $this->ion_auth->groups()->result_array();
    $currentGroups = $this->ion_auth->get_users_groups($id)->result();

    //process the phone number
    if (isset($user->phone) && !empty($user->phone)) {
        $user->phone = explode('-', $user->phone);
    } //isset($user->phone) && !empty($user->phone)

    //validate form input
    $this->form_validation->set_rules('first_name', $this->lang->line('edit_user_validation_fname_label'), 'required|xss_clean');
    $this->form_validation->set_rules('last_name', $this->lang->line('edit_user_validation_lname_label'), 'required|xss_clean');
    $this->form_validation->set_rules('email', $this->lang->line('create_user_validation_email_label'), 'required|valid_email');
    $this->form_validation->set_rules('company', $this->lang->line('edit_user_validation_company_label'), 'required|xss_clean');
    $this->form_validation->set_rules('groups', $this->lang->line('edit_user_validation_groups_label'), 'xss_clean');

    if (isset($_POST) && !empty($_POST)) {
        // do we have a valid request?
        if ($id != $this->input->post('id')) {
            show_error($this->lang->line('error_csrf'));
        } //$this->_valid_csrf_nonce() === FALSE || $id != $this->input->post('id')

        $data      = array(
            'first_name' => $this->input->post('first_name'),
            'last_name' => $this->input->post('last_name'),
            'company' => $this->input->post('company'),
            'email' => $this->input->post('email')
        );

        //Update the groups user belongs to
        $groupData = $this->input->post('groups');
        if (isset($groupData) && !empty($groupData)) {
            $this->ion_auth->remove_from_group('', $id);
            foreach ($groupData as $grp) {
                $this->ion_auth->add_to_group($grp, $id);
            } //$groupData as $grp
        } //isset($groupData) && !empty($groupData)

        //update the password if it was posted
        if ($this->input->post('password')) {
            $this->form_validation->set_rules('password', $this->lang->line('edit_user_validation_password_label'), 'required|min_length[' . $this->config->item('min_password_length', 'ion_auth') . ']|max_length[' . $this->config->item('max_password_length', 'ion_auth') . ']|matches[password_confirm]');
            $this->form_validation->set_rules('password_confirm', $this->lang->line('edit_user_validation_password_confirm_label'), 'required');
            $data['password'] = $this->input->post('password');
        } //$this->input->post('password')

        if ($this->form_validation->run() === TRUE) {
            $check = $this->ion_auth->update($user->id, $data);
            if (FALSE == $check) {
                $this->session->set_flashdata('message', $this->ion_auth->errors());
                redirect("auth/edit-user/$id", 'refresh');
            } else {
                //check to see if we are creating the user
                //redirect them back to the admin page
                $this->session->set_flashdata('message', "User Saved");
                redirect("auth/users", 'refresh');
            }
        } //$this->form_validation->run() === TRUE
    } //isset($_POST) && !empty($_POST)

    //display the edit user form
    $this->data['csrf']             = $this->_get_csrf_nonce();
    //set the flash data error message if there is one
    $this->data['message']          = (validation_errors() ? validation_errors() : ($this->ion_auth->errors() ? $this->ion_auth->errors() : $this->session->flashdata('message')));
    //pass the user to the view
    $this->data['user']             = $user;
    $this->data['groups']           = $groups;
    $this->data['currentGroups']    = $currentGroups;
    $this->data['first_name']       = array(
        'name' => 'first_name',
        'id' => 'first_name',
        'type' => 'text',
        'value' => $this->form_validation->set_value('first_name', $user->first_name)
    );
    $this->data['last_name']        = array(
        'name' => 'last_name',
        'id' => 'last_name',
        'type' => 'text',
        'value' => $this->form_validation->set_value('last_name', $user->last_name)
    );
    $this->data['company']          = array(
        'name' => 'company',
        'id' => 'company',
        'type' => 'text',
        'value' => $this->form_validation->set_value('company', $user->company)
    );
    $this->data['email']           = array(
        'name' => 'email',
        'id' => 'email',
        'type' => 'email',
        'value' => $this->form_validation->set_value('email', $user->email)
    );
    $this->data['password']         = array(
        'name' => 'password',
        'id' => 'password',
        'type' => 'password'
    );
    $this->data['password_confirm'] = array(
        'name' => 'password_confirm',
        'id' => 'password_confirm',
        'type' => 'password'
    );
    $this->_render_page('auth/admin/users/update', $this->data);
}

function _get_csrf_nonce() {
    $this->load->helper('string');
    $key   = random_string('alnum', 8);
    $value = random_string('alnum', 20);
    $this->session->set_flashdata('csrfkey', $key);
    $this->session->set_flashdata('csrfvalue', $value);
    return array(
        $key => $value
    );
}
function _valid_csrf_nonce() {
    if ($this->input->post($this->session->flashdata('csrfkey')) !== FALSE && 
            $this->input->post($this->session->flashdata('csrfkey')) == $this->session->flashdata('csrfvalue')) {
        return TRUE;
    } //$this->input->post($this->session->flashdata('csrfkey')) !== FALSE && $this->input->post($this->session->flashdata('csrfkey')) == $this->session->flashdata('csrfvalue')
    else {
        return FALSE;
    }
}

看法;

<h1><?php echo lang('edit_user_heading');?></h1>
<p><?php echo lang('edit_user_subheading');?></p>

<!--<div id="infoMessage" class="info"><?php echo $message;?></div>-->
<?php
if (isset($message)) {
?>
<div id="infoMessage" class="alert alert-info">
    <button type="button" class="close" data-dismiss="alert">&times;</button>
    <h4>Message</h4>
    <?php echo $message;?>
</div>
<?php
}
?>
<?php echo form_open(uri_string(), 'class="form-horizontal"'); ?>

    <div class="control-group <?php echo form_error_class('first_name') ?>">
        <label class="control-label" for="first_name">
            <?php echo lang('edit_user_fname_label'); ?>
        </label>
        <div class="controls">
            <input type="text" 
                   id="first_name" 
                   name="first_name" 
                   placeholder="<?php echo lang('edit_user_fname_label'); ?>"
                   value="<?php echo set_value('first_name', $first_name['value']); ?>"
                   class="error"/>
            <?php echo form_error('first_name'); ?>
        </div>
    </div>

    <div class="control-group <?php echo form_error_class('last_name') ?>">
        <label class="control-label" for="last_name">
            <?php echo lang('edit_user_lname_label'); ?>
        </label>
        <div class="controls">
            <input type="text" 
                   id="last_name" 
                   name="last_name" 
                   placeholder="<?php echo lang('edit_user_lname_label'); ?>"
                   value="<?php echo set_value('last_name', $last_name['value']); ?>"
                   class="error"/>
            <?php echo form_error('last_name'); ?>
        </div>
    </div>

    <div class="control-group <?php echo form_error_class('company') ?>">
        <label class="control-label" for="company">
            <?php echo lang('edit_user_company_label'); ?>
        </label>
        <div class="controls">
            <input type="text" 
                   id="company" 
                   name="company" 
                   placeholder="<?php echo lang('edit_user_company_label'); ?>"
                   value="<?php echo set_value('company', $company['value']); ?>"
                   class="error"/>
            <?php echo form_error('company'); ?>
        </div>
    </div>

    <div class="control-group <?php echo form_error_class('email') ?>">
        <label class="control-label" for="email">
            <?php echo lang('edit_user_email_label'); ?>
        </label>
        <div class="controls">
            <input type="text" 
                   id="email" 
                   name="email" 
                   placeholder="<?php echo lang('edit_user_email_label'); ?>"
                   value="<?php echo set_value('email', $email['value']); ?>"
                   class="error"/>
            <?php echo form_error('email'); ?>
        </div>
    </div>

    <div class="control-group <?php echo form_error_class('password') ?>">
        <label class="control-label" for="password">
            <?php echo lang('edit_user_password_label'); ?>
        </label>
        <div class="controls">
            <input type="password" 
                   id="password" 
                   name="password" 
                   placeholder="<?php echo lang('edit_user_password_label'); ?>"
                   value="<?php echo set_value('password'); ?>"
                   class="error"/>
            <?php echo form_error('password'); ?>
        </div>
    </div>

    <div class="control-group <?php echo form_error_class('password_confirm') ?>">
        <label class="control-label" for="password_confirm">
            <?php echo lang('edit_user_password_confirm_label'); ?>
        </label>
        <div class="controls">
            <input type="password" 
                   id="password_confirm" 
                   name="password_confirm" 
                   placeholder="<?php echo lang('edit_user_password_confirm_label'); ?>"
                   value=""
                   class="error"/>
            <?php echo form_error('password_confirm'); ?>
        </div>
    </div>

    <div class="control-group <?php echo form_error_class('groups') ?>">
        <div class="controls <?php echo form_error_class('groups') ?>">
            <h3><?php echo lang('edit_user_groups_heading');?></h3>
            <?php 
            foreach ($groups as $group) {
            ?>
            <label class="checkbox">
                <?php
                $gID=$group['id'];
                $checked = null;
                $item = null;
                foreach($currentGroups as $grp) {
                    if ($gID == $grp->id) {
                        $checked= ' checked="checked"';
                    break;
                    }
                }
                ?>
                <input type="checkbox" name="groups[]" value="<?php echo $group['id'];?>"<?php echo $checked;?>>
                <?php echo $group['name'];?>
            </label>
            <?php
            }
            ?>
        </div>
    </div>

    <?php echo form_hidden('id', $user->id);?>
    <?php echo form_hidden($csrf); ?>

     <div class="control-group">
        <div class="controls">
            <input type="submit" class="btn btn-success" value="<?php echo lang('edit_user_submit_btn'); ?>" />
        </div>
    </div>

<?php echo form_close();?>
4

3 回答 3

0

第一次检查

$this->session->set_flashdata('消息',

$this->ion_auth->errors()

); 有设定值

于 2013-05-30T07:58:31.060 回答
0

我找到了解决方案(或者这个修复程序只对我有用)。

我将配置中的会话驱动程序更改为使用来自 cookie 的本机会话。
config.php 的第 284 行 => $config['sess_driver'] = 'native';

黄金法则:永远不要相信 CI 会话!

于 2013-05-30T08:41:24.513 回答
0

关于 FLASHDATA CSRF 和 Flashdata 的一些概念:

FLASHDATA 将只对 NEXT 服务器请求可用,然后被自动清除!

例如:

AJAX 调用function_1,它发送CSRF key/valuefunction_1_success

function_1_success设置隐藏的输入字段CSFR key and value

并启用function_2,它将 POST 变量与 flashdata 进行比较

这就是它的工作原理(有或没有 AJAX,这只是一个例子)。

它是如何不工作的:如果你创建一个 php 函数

$this->session->set_flashdata('item', 'value')然后尝试与echo $this->session->flashdata('item')您一起阅读将得到一个空字符串,只有在刷新此功能后,您的 flashdata 值才会显示

于 2013-12-21T03:07:31.963 回答