在codeigniter

时间:2017-10-28 01:46:21

标签: php codeigniter

我有一个问题,我的登录表单在提交表单后立即丢失了会话数据。目前会话库正在自动加载。我正在使用CI_Sessions数据库来管理它。这是我的档案。

我的Login.php控制器功能

$this->form_validation->set_rules('user_login', 'User_Login', 'required');
$validation_results = $this->form_validation->run();

if ( $validation_results !== false ):
    if( isset( $_POST ) ):
        $options = array (
            "salt" => $this->config->config['password_salt'],
            "cost" => $this->config->config['password_cost']
        );
        $hash = password_hash($_POST['user_password'], PASSWORD_DEFAULT, $options);

        $this->load->library("users", "", "users_login_temp");
        $this->users_login_temp->get_object("user_login = '" . $_POST['user_login'] . "' AND user_pass = '" . $hash . "'" );

        if( !empty( $this->users_login_temp->id ) ):
            $_SESSION['user_name'] = $this->users_login_temp->name;
            $_SESSION['user_id'] = $this->users_login_temp->id;
            $_SESSION['user_email'] = $this->users_login_temp->user_email;

            //redirect( "admin/users/list" );
        else:
            $this->load->view('login/head', $data);
            $this->load->view('login/body-login', $data);
            $this->load->view('login/foot', $data);
        endif;
    endif;
else:
    $this->load->view('login/head', $data);
    $this->load->view('login/body-login', $data);
    $this->load->view('login/foot', $data);
endif;

这是我在pre_controller上运行的钩子

public function is_logged(){

    $path = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
    $segment = explode('/', $path);

    $page = $segment[2];

    if( isset( $_SESSION['user_id'] ) ):
        if( isset( $_SESSION['user_name'] ) ):
            //echo "We found some user data";
        else:
            if( $page == "login" ):
                //be silent
            else:
                <!-- ALL SESSION DATA LOST HERE 
                   Session is present but variables are gone
                 -->
                //redirect( "admin/login" );
            endif;
        endif;
    else:
        if( $page == "login" ):
            //be silent
        else:
            redirect( "admin/login" );
        endif;
    endif;
}

如果我在登录验证钩子下打印出会话变量,它会给我这个。

array(1) {
["__ci_last_regenerate"]=>
int(1509199090)
}

修订 - 我的会话配置

$config['sess_driver'] = 'database';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = "ci_sessions";
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = TRUE;
$config['cookie_prefix']    = 'gm';
$config['cookie_domain']    = 'localhost'; <--This needed to be set to ''
$config['cookie_path']      = '/';
$config['cookie_secure']    = FALSE;
$config['cookie_httponly']  = FALSE;

提前感谢任何指示或帮助

1 个答案:

答案 0 :(得分:1)

问题是在调用预控制器挂钩时未加载CI库session。而config / autoload.php还没有被包括在内#34; autoload&#34;它没有用。在session加载与会话相关的数据之前,无法访问。

仔细观察,这是第一个条件

if( isset( $_SESSION['user_id'] ) ):

永远不会评估为TRUE,因为除非您正在做一些事情来启动您未向我们展示的会话,否则$_SESSION超级全局在此之前尚不存在-controller hook正在运行。

使用此逻辑创建MY_Controller类(扩展CI_Controller)可能会更好。然后扩展基础以创建所有其他控制器。

<强>附录: 如果你不喜欢MY_Controller想法,你应该能够使用钩子,但是在不同的点上。创建控制器时包含autoload.php文件。因此,如果您使用&#39; post_controller_constructor&#39;钩点会话类应该准备就绪,它应该可以工作。

hook配置如下所示: 文件: APPATH / config / hooks.php

$hook['post_controller_constructor'][] = array(
  'class' => '',
  'function' => 'is_logged',
  'filename' => 'post_controller_construct_hook.php',
  'filepath' => 'hooks'
);

你的钩子功能看起来比必要的复杂一点。也许你是为测试目的而做的?无论如何,我建议尝试这个版本。

文件: APPATH / hooks / post_controller_construct_hook.php

function is_logged()
{
    $CI = get_instance();
    if($CI->router->method !== 'login')
    {
        if((!isset($_SESSION['user_id'])) OR (!isset($_SESSION['user_name'])))
        {
            redirect("admin/login");
        }
    }
}

构造控制器后,router类将可用。但是你必须让控制器的实例从钩子函数访问router。要求的&#34;方法&#34;使用$this->router->method属性很容易找到。如果router->method不是login,则会检查相应的$_SESSION数据并作出相应的反应。否则,钩子不需要做任何事情。

最后但并非最不重要的是,必须正确配置会话。这意味着为您选择的驱动程序适当地设置各种配置会话变量,同时确保您也正确设置Cookie相关变量。

在您的情况下尝试更改

$config['cookie_domain'] = 'localhost';

$config['cookie_domain'] = ''; //an empty string