In my home controller I'm checking whether the user is logged in or not. See the code below:
<?php
class Home extends Controller {
private $db;
private $session;
public function __construct($db, $session) {
$this->db = $db;
$this->session = $session;
parent::__construct($db, $session);
}
public function index() {
$this->view('home/index', array('user' => $x ) );
}
public function login() {
if( $this->session->loggedIn == true ) {
$this->index();
exit();
}
if( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
$sessionToDb = $this->session->startSession( $_POST['user_email'], $_POST['user_password'] );
if( $sessionToDb === true ) {
$this->index();
exit();
}
else {
$data['error'] = '<p>Fout tijdens inloggen.<br />'.$x.'</p>';
}
}
$data['url'] = $_SERVER['REQUEST_URI'];
$this->view('home/login', $data);
}
public function logout() {
$this->session->endSession();
$this->login();
exit();
}
}
?>
If the user is already logged in, he should be able to see the login screen, so I added this code:
public function login() {
if( $this->session->loggedIn == true ) {
$this->index();
exit();
}
Which works... however the URL stays the same: admin/home/login/, which could be confusing.
So alternatively I could redirect the user:
public function login() {
if( $this->session->loggedIn == true ) {
header('Location: /admin/home/index/';
exit();
}
Same goes for the logout()function.
Which is the better approach?
Related
I have a function index() in my Admin.php controller and I'm trying to execute the 'if' statement but it is executing the 'else' statement. The admin user and password that I am logging in is correct. There's something wrong in my code and could anyone here please help me. Thanks in advance. :)
Here's my code:
//Admin.php controller
<?php
class Admin extends CI_Controller
{
public function __construct()
{
parent::__construct();
if ($this->session->userdata('logged_in') !== TRUE) {
redirect('Login');
}
}
function index()
{
if ($this->session->userdata('level') === '1') {
$this->load->view('admin_view');
} else {
echo "Access Denied";
}
}
}
//Login.php controller
<?php
class Login extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('Login_model');
}
public function index()
{
$this->load->view('login_view');
}
public function auth()
{
$username = $this->input->post('user_name', TRUE);
$password = $this->input->post('user_pass', TRUE);
$result = $this->Login_model->check_user($username, $password);
if ($result->num_rows() > 0) {
$data = $result->row_array();
$name = $data['user_name'];
$level = $data['user_lvl'];
$sesdata = array(
'user_name' => $username,
'user_lvl' => $level,
'logged_in' => TRUE
);
$this->session->set_userdata($sesdata);
if ($level === '1') {
redirect('Admin');
} elseif ($level === '2') {
redirect('User');
}
} else {
echo "<script>alert('Access Denied');history.go(-1);</script>";
}
$this->load->view('login_view');
}
}
I Suggest use double equals instead triple equals
if ($this->session->userdata('level') == '1') {
$this->load->view('admin_view');
} else {
echo "Access Denied";
}
And also check if level is string or int..
The method -- initially called in index.php -- redirects to another page. The problem here is that variable $logged_in isn't getting assigned a new value... which means that when the variable is used in the other page, it is read as false.
NOTE: The assignment of session 'id' and session 'type' is correct.
class Session {
public $logged_in = false;
public function login($data) {
if ($data) {
$_SESSION['id'] = $data['id'];
$_SESSION['type'] = $data['type'];
$this->logged_in = true;
}
}
}
This is a class and therefore is lost (its properties are lost) at the end of the first scripts execution and then recreated in the second in its initial state.
Classes do not live across executions of the same script or any other script.
If you wish to maintain the objects state, you will have to save the state to a file or maybe the real SESSION so you can re-hydrate the data when the second script starts
session_start();
class Session {
public function login($data) {
if ($data) {
$_SESSION['id'] = $data['id'];
$_SESSION['type'] = $data['type'];
$_SESSION['logged_in'] = true;
}
}
// getter function
public function is_logged_in()
{
// just in case check
if ( isset($_SESSION['logged_in']) ) {
return $_SESSION['logged_in'] == true;
} else {
return false;
}
}
}
Called like this
$s = new Session();
if ( ! $s->is_logged_in() ) {
header('Location: index.php');
exit;
}
To keep it away from the SESSION completely you could
class Session {
public $id;
public $type;
public $logged_in;
public function __construct()
{
if ( file_exists('my_session.txt')) {
$obj = json_decode(file_get_contents('my_session.txt'));
foreach($obj as $prop => $val) {
$this->{$prop} = $val;
}
}
}
public function __destruct()
{
file_put_contents('my_session.txt', json_encode($this));
}
public function login($data) {
if ($data) {
$this->id = $data['id'];
$this->type = $data['type'];
$this->logged_in = true;
}
}
}
$obj = new Session();
$obj->login(array('id'=>99, 'type'=>'TEST'));
print_r($obj);
$obj = null;
echo 'object nulled' . PHP_EOL;
print_r($obj);
echo ' NOTHING should be printed' . PHP_EOL;
echo 'object rehydrated' . PHP_EOL;
$obj = new Session();
print_r($obj);
create another method check_login() to re-assign the values in the new page and call it within __construct()
function __construct(){
$this->check_login();
}
public function check_login(){
if(isset($_SESSION['id']) && isset($_SESSION['type']){
$this->logged_in = true;
} else {
$this->logged_in = false;
}
}
HOw do I pass $variable from comments() to someFunction()?
class Blog extends CI_Controller {
public function index()
{
echo 'Hello World!';
}
public function comments()
{
$variable = "Hello";
}
public function someFunction()
{
echo $variable;
}
}
** EDIT ** Feel free to point out any other mistakes if you wish
class Home extends CI_Controller {
private $idArray;
function __construct()
{
parent::__construct();
$this->load->model('home_model');
$this->load->library('tank_auth');
$this->load->library('form_validation');
}
public function index() {
$home_data['initial_two'] = $this->home_model->get_two_brands();
$home_data['user_id'] = $this->tank_auth->get_user_id();
$home_data['username'] = $this->tank_auth->get_username();
$this->load->view('home_view', $home_data);
}
public function get_two() {
$get_results = $this->home_model->get_two_brands();
if($get_results != false){
$html = '';
foreach($get_results as $result){
$html .= '<li>'.$result->brand.'</li>';
}
list($result1, $result2) = $get_results;
$idOne = $result1->id;
$idTwo = $result2->id;
$this->idArray = array($result1->id, $result2->id);
//var_dump($this->idArray);
$result = array('status' => 'ok', 'content' => $html);
header('Content-type: application/json');
echo json_encode($result);
exit();
}
}//public function get_two() {
function user_pick() {
$this->form_validation->set_rules('pick', 'Pick', 'required|trim|integer|xss_clean');
$this->form_validation->set_rules('notPick', 'Not Pick', 'required|trim|integer|xss_clean');
//$arr = $this->idArray;
var_dump($this->idArray); // This is NULL
$pick = $_POST['pick'];
$notPick = $_POST['notPick'];
$user_id = $this->tank_auth->get_user_id();
if ($this->form_validation->run() == FALSE)
{
$result = array('status' => 'no', 'content' => "No good!");
header('Content-type: application/json');
echo json_encode($result);
exit();
}else{//if ($this->form_validation->run() == FALSE || $do_input == NULL)
$upload = $this->home_model->user_pick($user_id, $pick, $notPick);
$result = array('status' => 'ok', 'content' => "Thank you!");
header('Content-type: application/json');
echo json_encode($result);
exit();
}//if ($this->form_validation->run() == FALSE || $do_input == NULL)
}
}//class Home extends CI_Controller { closing bracket
/* End of file home.php */
/* Location: ./application/controllers/home.php */
class Blog extends CI_Controller {
public function index()
{
echo 'Hello World!';
}
public function comments()
{
$_SESSION['variable'] = Array('k1'=>'v1','k2'=>'v2') ;
// Store the variable in session so it can be called
// in another page or ajax call
}
public function display()
{
echo $_SESSION['variable'] ;
}
}
// my index.php file
var $blog = new Blog() ;
$blog->comments() ;
//another ajax_called.php file, call in ajax on in another browser tab
var $blog = new Blog() ;
$blog->display() ;
I'm basically trying a session control. If the user is logged in, it's ok to move on. But if he's not logged in, then it will show a log-in screen and then die. However, when I use die or exit in the constructor, it does not show the log-in screen; it immediately dies. The code is as following:
private $username = null;
private $mongoid = null;
private $neoid = null;
public function __construct(){
parent::__construct();
// session to global
$this->username = $this->session->userdata( 'username');
$this->mongoid = $this->session->userdata( 'mongoid');
$this->neoid = $this->session->userdata( 'neoid');
// check if user is logged in
if( $this->username == "" || empty( $this->username)){
$this->load->view( 'access/login');
die;
}
}
It shows the log-in page if die is not written there, but with die, it does not show. Why do I want to use die? Because if I don't use, it moves on the index function and I don't want it to execute index function if the user is not logged in.
What is wrong here? What should I use to stop executing?
CodeIgniter does not instantly output the view when you load it with $this->load->view();, it puts the output of the view to the output buffer instead and after everything is loaded it flushes the whole output to the user. With that said, the problem you are seeing is that it buffers the output, then it dies without flushing it.
die is really bad and should not be used outside debugging, you should better use something like a variable switch. If it's only for the controllers scope, then you can make a
private $show_everything_else = true;
In the constructor:
if( $this->username == "" || empty( $this->username)){
$this->load->view( 'access/login');
$this->show_everything_else = false;
}
In any of the controller's methods:
if($this->show_everything_else) {
// ...
}
In any case, this solution is a quick fix and there are much better possibilities how to do this, but all of them require a different approach.
You can have a method and call it in constructor:
function __construct() {
parent::__construct();
$this->_is_logged_in();
}
and the method should look like this:
function _is_logged_in() {
$is_logged_in = $this->session->userdata('is_logged_in');
if (!isset($is_logged_in) || $is_logged_in != true) {
redirect('login');
die();
}
}
And, of course, you should have controller for login, which can look like this:
<?php
class Login extends CI_Controller {
function index() {
$this->load->view('LOGIN-VIEW');
}
function validate() {
$this->load->model('login_model');
$data = $this->login_model->validate();
if ($data != false) {
$data['is_logged_in'] = true;
$this->session->set_userdata($data);
redirect('MAIN-CONTROLLER-AFTER-LOGIN');
}
else {
$this->index();
}
}
function logout() {
$this->session->sess_destroy();
$this->index();
}
}
This what i posted, also preserve sessions in database.
Login model can be as primitive as this:
class Login_model extends CI_Model {
function validate() {
$this->db->where('username', $this->input->post('username'));
$this->db->where('password', md5($this->input->post('password')));
$query = $this->db->get('users');
if($query->num_rows == 1) {
$data = $query->row_array();
return $data;
} else {
return false;
}
}
The Controller class will automatically run the index() function. So, to make it work, you must return the index() if the login check in construct is failed. Here what you can do:
private $username = null;
private $mongoid = null;
private $neoid = null;
private $no_login = false;
public function __construct(){
parent::__construct();
// session to global
$this->username = $this->session->userdata( 'username');
$this->mongoid = $this->session->userdata( 'mongoid');
$this->neoid = $this->session->userdata( 'neoid');
// check if user is logged in
if( $this->username == "" || empty( $this->username)){
$this->load->view( 'access/login');
$this->no_login = true;
}
}
function index(){
if($this->no_login) return;
// another statement if login success.....
}
I am getting the following error when I check my site:
Fatal error: Call to a member function getUserID() on a non-object in /home/clientwo/public_html/main/registry/authenticate.php on line 104
This is the code:
<?php
class Authenticate {
private $user;
private $status;
private $loggedIn = false;
public function __construct(Registry $registry) {
$this->registry = $registry;
$this->status = 'User is logged out';
}
private function checkForAuthentication() {
if (isset($_SESSION['sn_auth_session_uid']) && $_SESSION['sn_auth_session_uid'] > 0) {
$this->sessionAuthenticate(intval($_SESSION['sn_auth_session_uid']));
}
}
private function sessionAuthenticate($id) {
//build a user model
require_once FRAMEWORK_PATH . 'model/user.php';
$this->user = new UserModel($this->registry, $id);
//check if user is valid etc
if ($this->user->isValid()) {
if (!$this->user->isActive()) {
$this->loggedIn = false;
$this->status = 'User has been deleted';
} else {
$this->loggedIn = true;
$this->status = 'User is logged in';
}
} else {
$this->loggedIn = false;
$this->status = 'User could not be found';
}
//make sure sessions are not set if user is not logged in
if (!$this->loggedIn) {
$this->logout();
}
}
public function login($username, $password) {
//first log out
$this->logout();
//execute query
$this->registry->getObject('mysql')->executeQuery("SELECT UserID FROM user WHERE Username='". $username . "' AND password='" . md5($password) . "'");
//check if query returned one row
if ($this->registry->getObject('mysql')->numRows() == 1) {
//get user row
$UserData = $this->registry->getObject('mysql')->getRow();
//build a user model
require_once FRAMEWORK_PATH . 'model/user.php';
$this->user = new UserModel($this->registry, $UserData['UserID']);
//check if user is valid and active etc
if ($this->user->isValid()) {
if ($this->user->isActive() == false) {
$this->loggedIn = false;
$this->status = 'User has been deleted';
} else {
$this->loggedIn = true;
$this->status = 'User is logged in';
$this->user->increaseLogins();
$this->user->update();
$_SESSION['sn_auth_session_uid'] = $this->user->getUserID();
}
} else {
$this->loggedIn = false;
$this->status = 'Authentication failed';
}
} else {
$this->loggedIn = false;
$this->status = 'Authentication failed';
}
}
function logout() {
//if such a session is set, unset it
if (isset($_SESSION['sn_auth_session_uid'])) {
unset($_SESSION['sn_auth_session_uid']);
}
//reset to logged out
$this->loggedIn = false;
//reset to null
$this->user = null;
}
public function isLoggedIn() {
$this->checkForAuthentication();
return $this->loggedIn;
}
public function isAdmin() {
$this->checkForAuthentication();
return $this->user->isAdmin();
}
public function getUser() {
$this->checkForAuthentication();
return $this->user;
}
public function getUserID() {
$this->checkForAuthentication();
return $this->user->getUserID();
}
public function getStatus() {
$this->checkForAuthentication();
return $this->status;
}
}
?>
This line is not returning the user object
$this->user = new UserModel($this->registry, $UserData['UserID']);