Codeigniter Blank Screen

Morning All

I’m completely baffled, i have created a multilevel user login system but upon login it just shows a blank page and the function in the url /Login/auth and no errors.
I’ve tried a million different things to see where the script is stopping and i believe its the Loginmodel.
I’m new to OOP php so be gentle :laughing:
I’m completely baffled as i should be getting an error with the password_verify (which i know is incorrect but thats another battle for once i’ve fixed this one).

Please can someone advise where i might be going wrong:-

Controller: Login.php

class Login extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->model('loginmodel');
        $this->load->helper('url_helper');
        $this->load->helper('form');
        $this->load->library('form_validation');
        //$this->load->library('database');
    }

    public function index()
    {
        $data = array();
        $data['metaDescription'] = 'Login Form Meta Desc';
        $data['metaKeywords'] = 'Login Form Keywords';
        $data['title'] = "Login Page";
        $this->load->view('templates/header');
        $this->load->view('pages/login/index', $data);
        $this->load->view('templates/footer');
    } 

    function auth()
    {
        $email    = $this->input->post('email',TRUE);
        $password = $this->input->post('password', TRUE);
        $validate = $this->loginmodel->validate($email,$password);
        
        if($validate->num_rows() > 0)
        {
            $data  = $validate->row_array();
            $fname       = $data['fname'];
            $email       = $data['email'];
            $user_level  = $data['user_level'];
            $companyname = $data['companyname'];
            $mobileno    = $data['mobileno'];
            $avatar      = $data['avatar'];
            $sesdata = array
            (
                'fname'       => $fname,
                'email'       => $email,
                'user_level'  => $user_level,
                'companyname' => $companyname,
                'mobileno'    => $mobileno,
                'avatar'      => $avatar,
                'logged_in' => TRUE
            );
            $this->session->set_userdata($sesdata);
            
            if($user_level === '99'){ // access login for admin
               redirect('Loginredir/admin');
            }
            elseif($user_level === '1') // access login for dealer
            { 
                redirect('Loginredir/dealer');
            }
            else
            {
                echo $this->session->set_flashdata('msg','Username or Password is Wrong');
                redirect('login');
            }
        }
     
            function logout()
            {
                $this->session->sess_destroy();
                redirect('login');
            }
    }
     
}

The Model: Loginmodel.php

class Loginmodel extends CI_Model 
{
    public function __construct()
    {
        $this->load->database();
    }

    function validate($email,$password)
    {

        $this->db->where('email',$email);
        $this->db->where('password',$password);
        password_verify('password',$password);

        $result = $this->db->get('dealers');
        
        return $result;
        
    }
     
}

& the redirect controller which is called by the main controller Login.php

class Loginredir extends CI_Controller
{
    function __construct()
    {
        parent::__construct();
        if($this->session->userdata('logged_in') !== TRUE)
        {
            redirect('login');
            echo 'bread';
        }
    }
    
    function admin()
    {
        //Allows access to admin only
        if($this->session->userdata('level')==='99')
        {
            $this->load->view('admin');
            $this->load->view('templates/adminheader2');
            echo 'eggs';
        }
        else
        {
            echo "You do not have permission to access this area!";
        }
    
    }
    
    function dealer()
    {
        //Allows access to staff only
        if($this->session->userdata('level')==='1')
        {
            $this->load->view('dealer');
            echo 'beef';
        }
        else
        {
            echo "Access Denied";
        }
    }
}

Ignore the echo’s as this was just me trying to test how far the script got to.

Thanks in advance all.

Check:

  1. writable folder is writable
  2. CI_ENVIRONMENT set to “development”
  3. PHP error_reporting(-1); and not modified later in any file
  4. CI error logging is working and change parameter to maximum errors
  5. force error by echo $x/yyyyy;

Hey John

Session folder is writable
'db_debug' => (ENVIRONMENT !== 'development'),
error_reporting(-1);
$config['log_threshold'] = 4;
Log File:

INFO - 2020-01-04 10:05:41 --> Config Class Initialized

INFO - 2020-01-04 10:05:41 --> Hooks Class Initialized

DEBUG - 2020-01-04 10:05:41 --> UTF-8 Support Enabled

INFO - 2020-01-04 10:05:41 --> Utf8 Class Initialized

INFO - 2020-01-04 10:05:41 --> URI Class Initialized

INFO - 2020-01-04 10:05:41 --> Router Class Initialized

INFO - 2020-01-04 10:05:41 --> Output Class Initialized

INFO - 2020-01-04 10:05:41 --> Security Class Initialized

DEBUG - 2020-01-04 10:05:41 --> Global POST, GET and COOKIE data sanitized

INFO - 2020-01-04 10:05:41 --> Input Class Initialized

INFO - 2020-01-04 10:05:41 --> Language Class Initialized

INFO - 2020-01-04 10:05:41 --> Loader Class Initialized

INFO - 2020-01-04 10:05:41 --> Helper loaded: url_helper

INFO - 2020-01-04 10:05:41 --> Database Driver Class Initialized

INFO - 2020-01-04 10:05:41 --> Session: Class initialized using 'files' driver.

INFO - 2020-01-04 10:05:41 --> Controller Class Initialized

INFO - 2020-01-04 10:05:41 --> Model "Loginmodel" initialized

INFO - 2020-01-04 10:05:41 --> Helper loaded: form_helper

INFO - 2020-01-04 10:05:41 --> Form Validation Class Initialized

INFO - 2020-01-04 10:05:41 --> Final output sent to browser

DEBUG - 2020-01-04 10:05:41 --> Total execution time: 0.0304

Also where would you suggest the Force Error echo goes? Model or Controller?

Thanks in advance.

I’m guessing and because of the above would try and find which view is being called by echoing the following before calling the view.

// Modify to suit requirements
echo '<pre>';// add line feeds to array elements 
echo __method__;
echo __line__;
print_r($this->variable_To_examine); 
die: // halt execution and show results in browser

// Script to call view

I don’t know what framework you’re using but this code:

$this->db->where('email',$email);
$this->db->where('password',$password);
password_verify('password',$password);

$result = $this->db->get('dealers');

appears to be specifying a “where” condition for the password matching the password that the user types. Unless you’re storing plain-text passwords, or the next line somehow alters things (and I think it looks like a call to password_verify that does nothing with the result), I can’t see how this would retrieve a user.

Thanks John, i placed it in the model as it had no effect in the controller and it fired an error of undefined property and then as from the variable in print_r it echoed the data that was supplied from the login form. Being new to OOP i’m not sure where to go from here.

Currently i’m learning Codeigniter. The passwords are currently hashed using password_hash. Being new to this framework & OOP i’m trying to figure out how to compare the hash in the db with the password that the user has submitted.

1 Like

Morning all gents.

I spent quite a few hours last night & this morning trying to figure this out, trying different things & reading the PHP manual.

Essentially, i’m stuck on trying to hash the password before its checked against the database.

In the controller i have the following which is called by the form;

function auth()
    {
        $email    = $this->input->post('email',TRUE);
        $password = $this->input->post('password', TRUE);
        $validate = $this->loginmodel->validate($email, $password);

So i see 2 ways of doing verifying the password vs the hash;

option 1: i hash the password from the form in the controller before its checked against the validate function which calls the model and checks the password hash against the db or…

option 2: inside the model i check the hash against the database and then return the data back to the controller to continue…

Model for reference:- (This is the best option i’ve come up with so far)

    function validate($email,$password)
    {
        

        $this->db->where('email',$email);
        $hash = $this->db->where('password', $password);
        return password_verify($hash, $password); 

        return $result;
    }
     

Of which i get an error of
Message: password_verify() expects parameter 1 to be string, object given :confounded:

Either way, i’m struggling on how best to write this. Please could one of you kind folk advise. (Be gentle i’m still new to OOP) :joy:

Thank you in advance.

Try debugging function validate(…) and printing the return value print_r($result);

I think you will get a surprise :slight_smile:

In my messing around last night i may have hashed out the line that calls the table in the db… :see_no_evil:

function validate($email,$password)
    {
        

        $this->db->where('email',$email);
        $hash = $this->db->where('password', $password);
        return password_verify($hash, $password); 
        $result = $this->db->get('dealers');

        //print_r($result);
        return $result;

Good spot John, unfortunately it doesn’t cure the issue of password_verify expects string but gets object. :weary:

I think the function calls return far too soon and will not execute any script after the return statement.

What value should function password_verify(…) return?

Should $result be the function return value?

Fair point.

I need password_verify to compare the users password in a hashed format against the users hashed password thats stored on the database.
Once the password_verify function has compared the 2 hashes and agreed they match for the script to continue accordingly.

Can you try the following:

// return password_verify($hash, $password); 
$tmp = password_verify($hash, $password); 
echo gettype($tmp);
die;

Hey John

Thanks for the suggestion. I got the following error:-
Message: password_verify() expects parameter 1 to be string, object given

and then Boolean echo’d out underneath the error message.

Is the $hash value a partial build query setting and the result used to get $this->db->get(…);?

function validate($email,$password)
{
// $this->db->where('email',$email);
// $hash = $this->db->where('password', $password);
// return password_verify($hash, $password); 
// $result = $this->db->get('dealers');

$this->db->where('email',$email);
$this->db->where('password', $password);
$hash = $this->db->get('dealers');
$result = password_verify($hash, $password);
var_dump($result);
// print_r($result);

return $result;
}//

@oli_d111 You need to retrieve the user by username then pass the retrieved hashed password to the password_verify function.

Trying to use the password in a where statement is fundamentally wrong. The hashed password stored in the database contains a builtin salt value which means that even using the same plaintext password you will never be able to generate the same hash. password_verify takes care of that for you.

And I know it’s off-topic but what is motivating you to learn CI? Which version? You might find that using a more popular framework might be more effective.

Hi John

To be fair, i’m just trying to figure out a way of getting the password_verify function to work. Whether it be initially called in the controller or model. Would it be helpful if i posted the remainder of the controller so that you can see?

Thanks for the code, unfortunately i got the same error + another:-

password_verify() expects parameter 1 to be string, object given

Call to a member function num_rows() on bool

Hi Ahundaiak

Appreciate your advice & i completely get it ultimately its what i’m aiming for but unfortunately being new to OOP i’m not sure how exactly to accomplish this.
As for learning CI (V3.0), it looked like an easier approach to learning MVC after battling and failing with installing Composer for Laravel i ended up just trying CI as it was uber quick to get up and running. Ultimatley i know that Laravel is better framework but for now i’m just learning. Besides frameworks aside, would i not have the same issue in Laravel as i do in CI for this pw verify issue?

Yes more code would help.

It is quite some time since I used CI’s Query builder and was never a big fan because I prefer to use a SQL statement.

The error messages show the query is returning a $hash object instead of a string.

Could you also add the following to show the generated SQL statement:

$sql = $this->db->get_compiled_select('dealers');
echo $sql;

Are you aware of CodeIgniter’s latest version? It started a couple of years ago and the new release is imminent. I get the impression and hopefully that this version is written "standing on the shoulder’s of giants". The new version appears to use only the best features from existing PHP Frameworks. I have used the GitHub version and it is a vast improvement over the first version first Released February 28, 2006!

Yes indeed I am aware that there is a yet to be released new version coming out. From my admittedly cursory reading, I don’t think CI4 will really share much with CI3. Hence my skepticism that CI is really the best platform for learning OOP. But of course this discussion is off-topic.

It just seems that it should be easy to query for the user’s password for a given email. And then use password_verify. But I am not seeing any evidence of that.

Hey John, heres the rest of the Controller for reference:-

public function auth()
    {
        $email    = $this->input->post('email',TRUE);
        $usrpassword = $this->input->post('password', TRUE);
        $validate = $this->loginmodel->validate($email, $usrpassword);

        
        if($validate->num_rows() > 0)
        {

            $data  = $validate->row_array();

            $firstname  = $data['fname'];
            $email = $data['email'];
            $level = $data['user_level'];
            $sesdata = array(
                'fname'      => $firstname,
                'email'      => $email,
                'user_level' => $level,
                'logged_in'  => TRUE
                
            );
            $this->session->set_userdata($sesdata);            
            
            if($level === '99'){ // access login for admin
               redirect('admin');
            }
            elseif($level === '1') // access login for dealer
            { 
                redirect('dealer');
            }
            else
            {
                echo $this->session->set_flashdata('msg','Username or Password is Wrong');
                redirect('login');
            }
        }
    }

Of course, the echo produced:
SELECT * FROM dealers``

I couldn’t agree more. I think there is probably a simple way i’m just not seeing it being new to OOP & MVC. Looking forward to seeing what CI4 holds though. Looking at the documentation it definitely looks positive.

If i could get ruddy composer installed i would start learning Laravel :joy: