错误codeigniter为同一用户生成多个会话

时间:2018-12-12 05:12:45

标签: codeigniter session codeigniter-3

我是该框架的新手。但是,使用codeigniter 3.19和Ion Auth 3创建一个项目,作为身份验证和用户注册的方法。

在我的本地服务器xampp窗口上,它可以完美地为每个用户生成一个会话。但是在我的带有linuxflare的web linux ubuntu 16.04,vestacp中,我每1 sg会生成10个会话,并且不断有数百万个会话记录,并且考虑到我的流量很少,我认为这是为每个用户创建重复会话的错误。

所有字段ip_address中的会话捕获为我提供了服务器的IP。

enter image description here 网上验证问题tvglu.net 附加的配置,非常感谢您的帮助。

/application/config/config.php 

$config['sess_driver'] = 'database'; 
$config['sess_cookie_name'] = 'cisession'; 
$config['sess_expiration'] = 7200; 
$config['sess_save_path'] = 'ci_session'; 
$config['sess_match_ip'] = FALSE; 
$config['sess_time_to_update'] = 300; 
$config['sess_regenerate_destroy'] = FALSE; 

$config['cookie_prefix']    = 'cisession'; 
$config['cookie_domain']    = ''; 
$config['cookie_path']        = '/'; 
$config['cookie_secure']    = FALSE; 
$config['cookie_httponly']     = FALSE; 

$config['proxy_ips'] = isset($_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : '';
/application/config/autoload.php 

$autoload['libraries'] = array('ion_auth'); 

tabla base de datos 

CREATE TABLE `ci_session` ( 
 `id` varchar(128) NOT NULL, 
 `ip_address` varchar(45) NOT NULL, 
 `timestamp` int(10) unsigned NOT NULL DEFAULT '0', 
 `data` blob NOT NULL, 
 PRIMARY KEY (`id`), 
 KEY `ci_sessions_timestamp` (`timestamp`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1

/application/libraries/Ion_auth.php 

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 

class Ion_auth 
{ 
    /** 
     * account status ('not_activated', etc ...) 
     * 
     * @var string 
     **/ 
    protected $status; 

    /** 
     * extra where 
     * 
     * @var array 
     **/ 
    public $_extra_where = array(); 

    /** 
     * extra set 
     * 
     * @var array 
     **/ 
    public $_extra_set = array(); 

    /** 
     * caching of users and their groups 
     * 
     * @var array 
     **/ 
    public $_cache_user_in_group; 

    /** 
     * __construct 
     * 
     * @return void 
     * @author Ben 
     **/ 
    public function __construct() 
    { 
        $this->load->config('ion_auth', TRUE); 
        $this->load->library(array('email')); 
        $this->lang->load('ion_auth'); 
        $this->load->helper(array('cookie', 'language','url')); 

        $this->load->library('session'); 

        $this->load->model('ion_auth_model'); 

        $this->_cache_user_in_group =& $this->ion_auth_model->_cache_user_in_group; 

        //auto-login the user if they are remembered 
        if (!$this->logged_in() && get_cookie($this->config->item('identity_cookie_name', 'ion_auth')) && get_cookie($this->config->item('remember_cookie_name', 'ion_auth'))) 
        { 
            $this->ion_auth_model->login_remembered_user(); 
        } 

        $email_config = $this->config->item('email_config', 'ion_auth'); 

        if ($this->config->item('use_ci_email', 'ion_auth') && isset($email_config) && is_array($email_config)) 
        { 
            $this->email->initialize($email_config); 
        } 

        $this->ion_auth_model->trigger_events('library_constructor'); 
    } 

    /** 
     * __call 
     * 
     * Acts as a simple way to call model methods without loads of stupid alias' 
     * 
     **/ 
    public function __call($method, $arguments) 
    { 
        if (!method_exists( $this->ion_auth_model, $method) ) 
        { 
            throw new Exception('Undefined method Ion_auth::' . $method . '() called'); 
        } 
        if($method == 'create_user') 
        { 
            return call_user_func_array(array($this, 'register'), $arguments); 
        } 
        if($method=='update_user') 
        { 
            return call_user_func_array(array($this, 'update'), $arguments); 
        } 
        return call_user_func_array( array($this->ion_auth_model, $method), $arguments); 
    } 

    /** 
     * __get 
     * 
     * Enables the use of CI super-global without having to define an extra variable. 
     * 
     * I can't remember where I first saw this, so thank you if you are the original author. -Militis 
     * 
     * [MENTION=178865]Access[/MENTION]    public 
     * @param    $var 
     * @return    mixed 
     */ 
    public function __get($var) 
    { 
        return get_instance()->$var; 
    } 


    /** 
     * forgotten password feature 
     * 
     * @return mixed  boolian / array 
     * @author Mathew 
     **/ 
    public function forgotten_password($identity)    //changed $email to $identity 
    { 
        if ( $this->ion_auth_model->forgotten_password($identity) )   //changed 
        { 
            // Get user information 
            $user = $this->where($this->config->item('identity', 'ion_auth'), $identity)->where('active', 1)->users()->row();  //changed to get_user_by_identity from email 

            if ($user) 
            { 
                $data = array( 
                    'identity'        => $user->{$this->config->item('identity', 'ion_auth')}, 
                    'forgotten_password_code' => $user->forgotten_password_code 
                ); 

                if(!$this->config->item('use_ci_email', 'ion_auth')) 
                { 
                    $this->set_message('forgot_password_successful'); 
                    return $data; 
                } 
                else 
                { 
                    $message = $this->load->view($this->config->item('email_templates', 'ion_auth').$this->config->item('email_forgot_password', 'ion_auth'), $data, true); 
                    $this->email->clear(); 
                    $this->email->from($this->config->item('admin_email', 'ion_auth'), $this->config->item('site_title', 'ion_auth')); 
                    $this->email->to($user->email); 
                    $this->email->subject($this->config->item('site_title', 'ion_auth') . ' - ' . $this->lang->line('email_forgotten_password_subject')); 
                    $this->email->message($message); 

                    if ($this->email->send()) 
                    { 
                        $this->set_message('forgot_password_successful'); 
                        return TRUE; 
                    } 
                    else 
                    { 
                        $this->set_error('forgot_password_unsuccessful'); 
                        return FALSE; 
                    } 
                } 
            } 
            else 
            { 
                $this->set_error('forgot_password_unsuccessful'); 
                return FALSE; 
            } 
        } 
        else 
        { 
            $this->set_error('forgot_password_unsuccessful'); 
            return FALSE; 
        } 
    } 

    /** 
     * forgotten_password_complete 
     * 
     * @return void 
     * @author Mathew 
     **/ 
    public function forgotten_password_complete($code) 
    { 
        $this->ion_auth_model->trigger_events('pre_password_change'); 

        $identity = $this->config->item('identity', 'ion_auth'); 
        $profile  = $this->where('forgotten_password_code', $code)->users()->row(); //pass the code to profile 

        if (!$profile) 
        { 
            $this->ion_auth_model->trigger_events(array('post_password_change', 'password_change_unsuccessful')); 
            $this->set_error('password_change_unsuccessful'); 
            return FALSE; 
        } 

        $new_password = $this->ion_auth_model->forgotten_password_complete($code, $profile->salt); 

        if ($new_password) 
        { 
            $data = array( 
                'identity'     => $profile->{$identity}, 
                'new_password' => $new_password 
            ); 
            if(!$this->config->item('use_ci_email', 'ion_auth')) 
            { 
                $this->set_message('password_change_successful'); 
                $this->ion_auth_model->trigger_events(array('post_password_change', 'password_change_successful')); 
                    return $data; 
            } 
            else 
            { 
                $message = $this->load->view($this->config->item('email_templates', 'ion_auth').$this->config->item('email_forgot_password_complete', 'ion_auth'), $data, true); 

                $this->email->clear(); 
                $this->email->from($this->config->item('admin_email', 'ion_auth'), $this->config->item('site_title', 'ion_auth')); 
                $this->email->to($profile->email); 
                $this->email->subject($this->config->item('site_title', 'ion_auth') . ' - ' . $this->lang->line('email_new_password_subject')); 
                $this->email->message($message); 

                if ($this->email->send()) 
                { 
                    $this->set_message('password_change_successful'); 
                    $this->ion_auth_model->trigger_events(array('post_password_change', 'password_change_successful')); 
                    return TRUE; 
                } 
                else 
                { 
                    $this->set_error('password_change_unsuccessful'); 
                    $this->ion_auth_model->trigger_events(array('post_password_change', 'password_change_unsuccessful')); 
                    return FALSE; 
                } 

            } 
        } 

        $this->ion_auth_model->trigger_events(array('post_password_change', 'password_change_unsuccessful')); 
        return FALSE; 
    } 

    /** 
     * forgotten_password_check 
     * 
     * @return void 
     * @author Michael 
     **/ 
    public function forgotten_password_check($code) 
    { 
        $profile = $this->where('forgotten_password_code', $code)->users()->row(); //pass the code to profile 

        if (!is_object($profile)) 
        { 
            $this->set_error('password_change_unsuccessful'); 
            return FALSE; 
        } 
        else 
        { 
            if ($this->config->item('forgot_password_expiration', 'ion_auth') > 0) { 
                //Make sure it isn't expired 
                $expiration = $this->config->item('forgot_password_expiration', 'ion_auth'); 
                if (time() - $profile->forgotten_password_time > $expiration) { 
                    //it has expired 
                    $this->clear_forgotten_password_code($code); 
                    $this->set_error('password_change_unsuccessful'); 
                    return FALSE; 
                } 
            } 
            return $profile; 
        } 
    } 

    /** 
     * register 
     * 
     * @return void 
     * @author Mathew 
     **/ 
    public function register($username, $password, $email, $additional_data = array(), $group_ids = array()) //need to test email activation 
    { 
        $this->ion_auth_model->trigger_events('pre_account_creation'); 

        $email_activation = $this->config->item('email_activation', 'ion_auth'); 

        if (!$email_activation) 
        { 
            $id = $this->ion_auth_model->register($username, $password, $email, $additional_data, $group_ids); 
            if ($id !== FALSE) 
            { 
                $this->set_message('account_creation_successful'); 
                $this->ion_auth_model->trigger_events(array('post_account_creation', 'post_account_creation_successful')); 
                return $id; 
            } 
            else 
            { 
                $this->set_error('account_creation_unsuccessful'); 
                $this->ion_auth_model->trigger_events(array('post_account_creation', 'post_account_creation_unsuccessful')); 
                return FALSE; 
            } 
        } 
        else 
        { 
            $id = $this->ion_auth_model->register($username, $password, $email, $additional_data, $group_ids); 

            if (!$id) 
            { 
                $this->set_error('account_creation_unsuccessful'); 
                return FALSE; 
            } 

            $deactivate = $this->ion_auth_model->deactivate($id); 

            if (!$deactivate) 
            { 
                $this->set_error('deactivate_unsuccessful'); 
                $this->ion_auth_model->trigger_events(array('post_account_creation', 'post_account_creation_unsuccessful')); 
                return FALSE; 
            } 

            $activation_code = $this->ion_auth_model->activation_code; 
            $identity        = $this->config->item('identity', 'ion_auth'); 
            $user            = $this->ion_auth_model->user($id)->row(); 

            $data = array( 
                'identity'   => $user->{$identity}, 
                'id'         => $user->id, 
                'email'      => $email, 
                'activation' => $activation_code, 
            ); 
            if(!$this->config->item('use_ci_email', 'ion_auth')) 
            { 
                $this->ion_auth_model->trigger_events(array('post_account_creation', 'post_account_creation_successful', 'activation_email_successful')); 
                $this->set_message('activation_email_successful'); 
                    return $data; 
            } 
            else 
            { 
                $message = $this->load->view($this->config->item('email_templates', 'ion_auth').$this->config->item('email_activate', 'ion_auth'), $data, true); 

                $this->email->clear(); 
                $this->email->from($this->config->item('admin_email', 'ion_auth'), $this->config->item('site_title', 'ion_auth')); 
                $this->email->to($email); 
                $this->email->subject($this->config->item('site_title', 'ion_auth') . ' - ' . $this->lang->line('email_activation_subject')); 
                $this->email->message($message); 

                if ($this->email->send() == TRUE) 
                { 
                    $this->ion_auth_model->trigger_events(array('post_account_creation', 'post_account_creation_successful', 'activation_email_successful')); 
                    $this->set_message('activation_email_successful'); 
                    return $id; 
                } 

            } 

            $this->ion_auth_model->trigger_events(array('post_account_creation', 'post_account_creation_unsuccessful', 'activation_email_unsuccessful')); 
            $this->set_error('activation_email_unsuccessful'); 
            return FALSE; 
        } 
    } 

    /** 
     * logout 
     * 
     * @return void 
     * @author Mathew 
     **/ 
    public function logout() 
    { 
        $this->ion_auth_model->trigger_events('logout'); 

        $identity = $this->config->item('identity', 'ion_auth'); 
                $this->session->unset_userdata( array($identity => '', 'id' => '', 'user_id' => '') ); 

        //delete the remember me cookies if they exist 
        if (get_cookie($this->config->item('identity_cookie_name', 'ion_auth'))) 
        { 
            delete_cookie($this->config->item('identity_cookie_name', 'ion_auth')); 
        } 
        if (get_cookie($this->config->item('remember_cookie_name', 'ion_auth'))) 
        { 
            delete_cookie($this->config->item('remember_cookie_name', 'ion_auth')); 
        } 

        //Destroy the session 
        $this->session->sess_destroy(); 

        //Recreate the session 
        if (substr(CI_VERSION, 0, 1) == '2') 
        { 
            $this->session->sess_create(); 
        } 
        else 
        { 
            $this->session->sess_regenerate(TRUE); 
        } 

        $this->set_message('logout_successful'); 
        return TRUE; 
    } 

    /** 
     * logged_in 
     * 
     * @return bool 
     * @author Mathew 
     **/ 
    public function logged_in() 
    { 
        $this->ion_auth_model->trigger_events('logged_in'); 

        return (bool) $this->session->userdata('identity'); 
    } 

    /** 
     * logged_in 
     * 
     * @return integer 
     * @author jrmadsen67 
     **/ 
    public function get_user_id() 
    { 
        $user_id = $this->session->userdata('user_id'); 
        if (!empty($user_id)) 
        { 
            return $user_id; 
        } 
        return null; 
    } 


    /** 
     * is_admin 
     * 
     * @return bool 
     * @author Ben Edmunds 
     **/ 
    public function is_admin($id=false) 
    { 
        $this->ion_auth_model->trigger_events('is_admin'); 

        $admin_group = $this->config->item('admin_group', 'ion_auth'); 

        return $this->in_group($admin_group, $id); 
    } 

    /** 
     * in_group 
     * 
     * @param mixed group(s) to check 
     * @param bool user id 
     * @param bool check if all groups is present, or any of the groups 
     * 
     * @return bool 
     * @author Phil Sturgeon 
     **/ 
    public function in_group($check_group, $id=false, $check_all = false) 
    { 
        $this->ion_auth_model->trigger_events('in_group'); 

        $id || $id = $this->session->userdata('user_id'); 

        if (!is_array($check_group)) 
        { 
            $check_group = array($check_group); 
        } 

        if (isset($this->_cache_user_in_group[$id])) 
        { 
            $groups_array = $this->_cache_user_in_group[$id]; 
        } 
        else 
        { 
            $users_groups = $this->ion_auth_model->get_users_groups($id)->result(); 
            $groups_array = array(); 
            foreach ($users_groups as $group) 
            { 
                $groups_array[$group->id] = $group->name; 
            } 
            $this->_cache_user_in_group[$id] = $groups_array; 
        } 
        foreach ($check_group as $key => $value) 
        { 
            $groups = (is_string($value)) ? $groups_array : array_keys($groups_array); 

            /** 
             * if !all (default), in_array 
             * if all, !in_array 
             */ 
            if (in_array($value, $groups) xor $check_all) 
            { 
                /** 
                 * if !all (default), true 
                 * if all, false 
                 */ 
                return !$check_all; 
            } 
        } 
        /** 
         * if !all (default), false 
         * if all, true 
         */ 
        return $check_all; 
    } 
}

1 个答案:

答案 0 :(得分:1)

几个月前,我遇到了类似的问题。

由于您处在cloudflare上,它具有多个出口节点,这些节点需要不断了解您的应用程序是否处于运行状态,因此您可能会受到多项运行状况检查的打击。如果将运行状况检查定向到加载了会话库的站点的一部分,则每次运行状况检查都将创建一个空会话(您可以检查...表中的大多数会话行将具有一个空的data字段)

由于您要自动加载ion auth,并且在其中要加载构造函数中的会话库,因此相加。

有一些解决方法: 您可能会让Cloudflare将其运行状况检查指向站点的不使用会话的某些部分。如果可以的话,那是最简单/最简单的解决方法,并且需要零编码。

如果您无法更改Cloudflare发送支票的位置,则不会丢失所有信息。您可以为运行状况检查所在的特定控制器/方法设置不会自动加载Ion和/或会话库的异常。有关如何执行此操作的很好的指导,可以在这里找到:

Codeigniter: Change autoload libraries for one controller?

如果这也不是一种选择,并且您无法通过这种方式“保护”自己,则可以设置一个简单的管家脚本,该脚本会定期删除空会话。这不是最佳选择,但有帮助