我有一个问题,我的登录表单在提交表单后立即丢失了会话数据。目前会话库正在自动加载。我正在使用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;
提前感谢任何指示或帮助
答案 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