Cannot exit in CodeIgniter constructor - php

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.....
}

Related

Call to member data on userdata() on a non object

I am getting error
Call to member data on userdata() on a non object
when i am setting the Session $this->session->userdata('userName', $userName);
Login Controller
<?php
class loginController extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->library('session');
}
public function login() {
$this->load->View("template/header");
$this->load->View("login_view");
}
public function AuthenticateUser() {
//Is the UserName and Password values retrieved?
if( isset( $_POST['userName'] ) && isset( $_POST['password'] ) ) {
$this->load->library("UserFactory");
$userName = addslashes($_POST['userName']);
$password = addslashes($_POST['password']);
//Get User details based on UserName and Password
$data = array(
"users" => $this->userfactory->checkLogin($userName, $password)
);
if($data["users"] != null) {
$this->session->userdata('userName', $userName);
}
header('Content-Type: application/json');
echo json_encode( $data["users"] );
}
}
}
?>
Any Idea why this is happening ?
$this->session->userdata()
this use to retrieve data from session.
to set session use this
$this->session->set_userdata('some_name', 'some_value');
Wrong Argument on here
if($data["users"] != null) {
$this->session->userdata('userName', $userName); # retrieving data
}
You trying to access data from session without setting it
Make sure you have loaded $this->load->library('session');
change
if($data["users"] != null) {
$this->session->userdata('userName', $userName);
}
to
if($data["users"] != null) {
$this->session->set_userdata('userName', $userName);
}
More on session read this http://w3code.in/2015/10/session-handling-in-codeigniter/

PHP won't set session to TRUE

I'm trying to create a login system but it doesn't seem to set "Session=true". Please help I'm stuck with this for too long now.
Session starts
Checked all my code
No PHP errors
and No database Errors
Login Page:
if($session->is_logged_in()) {
redirect_to("index.php");
}
if (isset($_POST['submit'])) { // Form has been submitted.
$user_name = trim($_POST['user_name']);
$password = trim($_POST['password']);
// Check database to see if username/password exist.
$found_user = User::authenticate($user_name, $password);
if ($found_user) {
$session->login($found_user);
redirect_to("index.php");
} else {
// username/password combo was not found in the database
$message = "Username/password combination incorrect.";
}
} else { // Form has not been submitted.
$user_name = "";
$password = "";
}
Session Class:
class Session {
private $logged_in=false;
public $user_id;
function __construct() {
session_start();
$this->check_login();
if($this->logged_in) {
// actions to take right away if user is logged in
} else {
// actions to take right away if user is not logged in
}
}
public function is_logged_in() {
return $this->logged_in;
}
public function login($user) {
// database should find user based on username/password
if($user){
$this->user_id = $_SESSION['user_id'] = $user->id;
$this->logged_in = true;
}
}
public function logout() {
unset($_SESSION['user_id']);
unset($this->user_id);
$this->logged_in = false;
}
private function check_login() {
if(isset($_SESSION['user_id'])) {
$this->user_id = $_SESSION['user_id'];
$this->logged_in = true;
} else {
unset($this->user_id);
$this->logged_in = false;
}
}
}
$session = new Session();
index page:
if (!$session->is_logged_in()) { redirect_to("login.php");
Authorize Method:
public static function authenticate($user_name="", $password="") {
global $database;
$user_name = $database->escape_value($user_name);
$password = $database->escape_value($password);
$sql="SELECT * FROM users WHERE user_name='{$user_name}' AND password ='{$password}' LIMIT 1";
$result_array = self::find_by_sql($sql);
return !empty($result_array) ? array_shift($result_array) : false;
}
Change your is_logged_in() function to:
public function is_logged_in() {
$this->check_login();
return $this->logged_in;
}
Otherwise is_logged_in() will always return false on each new request (such as redirecting between pages). By calling check_login() first, it will set the logged_in variable with the value (true or false, dependent on if $_SESSION['user_id'] is set.
EDIT:
I'm sorry, I've overlooked the line in the constructor where you already call $this->check_login();
Another thing is that the authenticate function returns an Array instead of an object. So, change the following:
$this->user_id = $_SESSION['user_id'] = $user->id;
To
$this->user_id = $_SESSION['user_id'] = $user['id'];
Finally I have found the solution to this.
Guess what? It wasn't my codes fault but it was my servers(WAMP 2) fault. So, I uninstalled WAMP 2 and updated to the newer version WAMP 2.5. Solved my problem and no more getting redirect to login page!

Auth Component's user function not working in case multiple routing

I have routed my site as admin moderator. Means When I use Auth component my sessions are created as Auth->Admin->id & Auth->Moderator->id And Auth->User->id this way.
Now I tried function $this->Auth->user its returning null why??
As I know $this->Auth->user returns session.
I know the traditional way of $this->Session->reads('Auth.Admin') and else but I want to use Auth->user function why its not working
Please use this to get user session data.
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
}
public function index() {
pr($this->Auth->User());
}
auth_helper:<?php
defined('BASEPATH') OR exit('No direct script access allowed');
if ( ! function_exists('auth'))
{
function auth()
{
$CI =& get_instance();
$CI->load->model('Auth_model');
return $CI->Auth_model;
}
function Adminauth($admin_id)
{
if($admin_id == false)
{
redirect('login');
}
}
}
auth_model:
<?php
if (!defined('BASEPATH')) {
exit('No direct script access allowed');
}
class Auth_model extends CI_Model {
private $user = null;
private $ci = null;
public function __construct() {
parent::__construct();
$CI =& get_instance();
$this->ci = $CI;
}
public function get($name, $default = null){
if ($this->ci->session->has_userdata('auth.Adminuser_id')) {
$user_id = $this->ci->session->userdata('auth.Adminuser_id');
$this->user = $this->db->query("SELECT * FROM members WHERE u_id=? LIMIT 1", array($user_id))->row();
}
return !empty($this->user) ? $this->user->u_name : $default;
}
public function is_logged(){
return $this->ci->session->has_userdata('auth.Adminuser_id');
}
public function login($user_id){
return $this->ci->session->set_userdata('auth.Adminuser_id', $user_id);
}
public function logout(){
return $this->ci->session->unset_userdata('auth.Adminuser_id');
}
}

How to redirect to another action in Controller_Template?

I've this class that extends Controller_Template.
<?php defined('SYSPATH') or die('No direct script access.');
abstract class Controller_Common extends Controller_Template {
public $template = 'main';
public function before()
{
parent::before();
View::set_global('title', 'Мій сайт');
View::set_global('description', 'Сайт');
$this->template->content = '';
$this->template->styles = array('style');
$this->template->scripts = '';
}
} // End Common
In controller class I want to redirect to another action.
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_User extends Controller_Common {
public function action_info()
{
$this->template->content = View::factory('user/info')
->bind('user', $user);
// Load the user information
$user = Auth::instance()->get_user();
// if a user is not logged in, redirect to login page
if (!$user)
{
Request::current()->redirect('user/login');
}
}
public function action_login()
{
try{
if (HTTP_Request::POST == $this->request->method())
{
// Attempt to login user
$remember = array_key_exists('remember', $this->request->post()) ? (bool) $this->request->post('remember') : FALSE;
$username = $this->request->post('username');
$password = $this->request->post('password');
$user = Auth::instance()->login($username, $password, true);
$logged = Auth::instance()->logged_in('login');
// If successful, redirect user
if($user)
{
$this->redirect("user/info");
}
else
{
$message = 'Login failed';
}
}
/**/
}catch(Exception $e)
{
var_dump($e->getMessage());
}
$this->template->content = View::factory('user/login')
->bind('message', $message);
}
public function action_logout()
{
/*// Log user out
Auth::instance()->logout();
// Redirect to login page
Request::current()->redirect('user/login');*/
}
}
?>
I use this code in action_login
$this->redirect("user/info");
But redirection doesn't work. How to fix this problem?
I use Kohana 3.3.0 version
Request class has no redirect method. See userguide:
HTTP::redirect('user/login', 302);
or
self::redirect('user/login', 302);
PS. Controller::redirect() is a static method, so userguide example seems to be incorrect.
Remove try..catch from action_login, http::redirect use exceptions for redirect, HTTP::Redirect.
P.S. You can use $this or self for redirect, $this vs self

Codeigniter execute code in every controller

I'm rather new to Codeigniter, so I may be going about this the wrong way. In the header for my template, I have a spot for displaying account information or a message to log in.
In order for it to work properly, each controller obviously need to have the same code. To avoid this, the user guide says I should be able to extend CI_Controller and it automatically includes that code. However, that's not working for me. Here's what I've got.
application/core/MY_Controller.php:
<?php
class MY_Controller extends CI_Controller {
function __construct()
{
parent::__construct();
$this->load->database();
$this->load->model('user_model');
if ( $this->user_model->validateToken ( $this->input->cookie('session_token', TRUE) ) )
{
$data['login_info'] = 'Logged in as '. $this->user_model->getUsernameAsLink($this->input->cookie('session_token', TRUE)).'<BR />
Control Panel';
}
else
{
$data['login_info'] = 'You are not logged in<BR />
Log In';
}
}
}
?>
the model it references:
<?php
class User_model extends CI_Model {
public function __construct()
{
}
public function validateToken($token)
{
// Get token from database to check against cookie
$query = $this->db->query('SELECT `login_token` FROM `Users` WHERE `login_token` = "'.$token.'"');
// Match Found?
$rowCount = $query->num_rows();
if ( $rowCount == 1 ) {
return true;
} else {
return false;
}
}
public function getUsernameAsLink ( $token )
{
// Get token from database to check against cookie
$query = $this->db->query('SELECT `username` FROM `Users` WHERE `login_token` = "'.$token.'"');
foreach( $query->result() as $row ) {
$username = $row->username;
}
$returnString = ''.ucfirst ( $username ).'';
return $returnString;
}
}
?>
I'm getting notice errors saying that the $data['login_info'] value doesn't exist. Is there anything I've left out to keep it from processing the extension to MY_Controller?
For $data to be available in your other controllers, you need to make it available. Try setting it to $this->data and using that same thing in the other controllers.

Categories