Welcome Guest, Not a member yet? Register   Sign In
(SOLVED)Need Login Help using Erkanaauth
#1

[eluser]zimco[/eluser]
I'm trying to create the most basic login area for my application: one admin user and password stored in a mysql table.

I tried following the tutorial by Alex Biddle that uses Erkanaauth but i've mucked it all up and can't get it to work.

Can someone tell me what i am doing wrong and how to fix it?

File locations:
application/libraries/Erkanaauth.php
application/helpers/erkanaauth_helper.php
application/controllers/admin/authcontroller.php
application/controllers/admin/login.php
application/views/admin/content-login.php

The mysql table was created with the following command:
CREATE TABLE `users` (
`id` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT,
`username` varchar(10) NOT NULL,
`password` varchar(10) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
);

The admin user was inserted into the database with
INSERT INTO users (username, password) VALUES ("admin", sha1("demo"));

Here's the code for my login.php controller:

Code:
<?php

class Login extends Controller
{

    function Login()
    {
        parent::Controller();
        $this->base = $this->config->item('base_url');
        $this->css = $this->config->item('css');
        $this->load->library('validation');
        $this->load->helper('form');
        $this->load->library('Erkanaauth');
    }


/*======================================================================*\
    Function:    index()
    Purpose:    Provide the Login entry page.
    Input:        
    Output:        Display login page view
\*======================================================================*/
    function index()
    {
        $login_form_rules = array
        (
            'username' => 'callback_check_username',
            'password' => 'required'
        );
        $login_form_fields = array
        (
            'username' => 'username',
            'password' => 'password'
        );

        $this->validation->set_fields($login_form_fields);
        $this->validation->set_rules($login_form_rules);
        if ($this->validation->run() == FALSE)
        {
          //Load the view file
          $data['css'] = $this->css;
          $data['base'] = $this->base;
          // set the header view
          $data['header'] = $this->load->view('header', '');
          // set the page content
          $data['content'] = $this->load->view('admin/content-login', $data);
          // set the footer view
          $data['footer'] = $this->load->view('footer', '');
        }
        else
        {
            redirect('admin/success');
        }

    }


/*======================================================================*\
    Function:    check_username($username)
    Purpose:    
    Input:        
    Output:        
\*======================================================================*/
    function check_username($username)
    {
        $this->load->helper('security');
        $password = dohash($this->input->post('password'));
        if ($this->erkanaauth->try_login(array('username' => $username, 'password' => $password)))
        {
            return True;
        }
        else
        {
            $this->validation->set_message('check_username', 'Incorrect login info.');
            return False;
        }
    }
    
/*======================================================================*\
                                  END
\*======================================================================*/
}

?>

Here's the code for my login view, content-login.php:

Code:
<div id="content">

<div id="loginform">
<h1>Login</h1>
&lt;?php echo $this->validation->error_string; ?&gt;

&lt;?php $attributes = array('id' => 'login'); ?&gt;
&lt;?php echo form_open('admin/index', $attributes); ?&gt;

  <p>
  <label for="username">Username: </label>
  &lt;?php
  $username = array(
              'username'    => 'username',
              'maxlength'   => '10',
              'size'        => '25',
            );
  echo form_input($username);
  ?&gt;
  <p>
  <label for="password">Password: </label>
  &lt;?php
  $password = array(
              'password'    => 'password',
              'maxlength'   => '10',
              'size'        => '25',
            );
  echo form_input($password);
  ?&gt;
  </p>
  <p>
    &lt;?php echo form_submit('submit', 'Submit'); ?&gt;
  </p>  
  
  &lt;?php echo form_close(); ?&gt;
  
</div>

</div>
#2

[eluser]ontguy[/eluser]
Nothing stands out. Is giving an error or the login just doesn't work?
#3

[eluser]zimco[/eluser]
It's like the input is never being processed: you can type anything in username and password or leave them completely blank and it always goes to admin/index and produces a 404 Page Not Found The page you requested was not found, instead of outputting a validation error msg or returning me to the login page.
#4

[eluser]ontguy[/eluser]
Code:
$username = array(
              'username'    => 'username',
              'maxlength'   => '10',
              'size'        => '25',
            );

should be the following, to give the input a proper name and adding the validated value in case of an error:
Code:
$username = array(
              'name'    => 'username',
              'value'    => $this->validation->username,
              'maxlength'   => '10',
              'size'        => '25',
            );

Is admin/index the uri that loads the admin login?
Do the views header.php and footer.php exists?

Is a particular reason you are assigning the view to a variable when it is not setup to return a string; it maybe functionality you'll add in the future?
Code:
$data['header'] = $this->load->view('header', '');
#5

[eluser]Alex Biddle[/eluser]
I think the problem is with the routing, try adding this to your routes.php config file:

Code:
$route['admin/login'] = 'admin/login';

Also I think you need to change

Code:
&lt;?php echo form_open('admin/index', $attributes); ?&gt;

to

Code:
&lt;?php echo form_open('admin/login', $attributes); ?&gt;
#6

[eluser]zimco[/eluser]
Thanks for all the responses it is closer to working now, I changed the form_open statement as suggested to:
Code:
&lt;?php echo form_open('admin/login', $attributes); ?&gt;
That at least got it to start sending validation error messages, but now whatever i type in the password field results in the error The password field must have a value. even if i give it the correct value or anything else.

I'll keep working on it this weekend and report back.

Thanks for all the help the CodeIgniter community is the best!
#7

[eluser]ontguy[/eluser]
In the view, this:
Code:
$password = array(
              'password'    => 'password',
              'maxlength'   => '10',
              'size'        => '25',
            );
echo form_input($password);

should be:
Code:
$password = array(
              'name'    => 'password',
              'maxlength'   => '10',
              'size'        => '25',
            );
echo form_password($password);
#8

[eluser]zimco[/eluser]
I finally solved my login problems, but it was not easy. Besides the errors that people already pointed out as posted above there were errors that were not quite so obvious:
the copy of Erkanaauth that i had downloaded via the link posted in this forum thread was old and used getwhere(), which has been deprecated, so i had to replace all those calls to the new get_where, but the most irratating error was the fact that i created my table as posted above with:
Code:
`password` varchar(10) NOT NULL

Guess what happens when you SHA1 your password and insert it into the database? It's longer than 10 characters, but gets put into the database with just the first ten characters, so when you go to check for the dohash(password) it will never match (my-DUH moment)! Once i changed the password field to be long enough for a hashed password (`password` varchar(128) NOT NULL) it worked as expected.

Thanks for everybodies help and i've posted my finished working code below in hopes that it will help others learning to code a login box. FYI, i changed the name of my controller and view to sentry.php and content-sentry.php

I added an encryption key to my password by following Elliot Haughin's instructions and adding his _prep_password($password) function to the end of Erkanaauth which i will paste below too. Open-up your applications config.php file find and add a set of random numbers and letters at least 32 chararcters long:
Code:
$config['encryption_key'] = "";

Remember to change your users database password field to the password.encrypted value.

Here's the code for my login controller, named sentry.php

Code:
&lt;?php

class Sentry extends Controller
{

    function Sentry()
    {
        parent::Controller();
        $this->base = $this->config->item('base_url');
        $this->css = $this->config->item('css');
        $this->load->library('validation');
        $this->load->helper('form','security');
        $this->load->library('Erkanaauth');
    }


/*======================================================================*\
    Function:    index()
    Purpose:    Provide the Login entry page.
    Input:        
    Output:        Display login page view
\*======================================================================*/
    function index()
    {
        $this->load->helper(array('form', 'url'));
        
        $this->load->library('validation');
        
//$rules['username'] = "trim|required|min_length[5]|max_length[10]|xss_clean";
$rules['username']    = "callback_check_username";
$rules['password'] = "trim|required";
        
        $this->validation->set_rules($rules);
                
        if ($this->validation->run() == FALSE)
        {
            //Load the view file
          $data['css'] = $this->css;
          $data['base'] = $this->base;
          // set the header view
          $data['header'] = $this->load->view('header', '');
          // set the page content
          $data['content'] = $this->load->view('admin/content-sentry', $data);
          // set the footer view
          $data['footer'] = $this->load->view('footer', '');
        }
        else
        {
            //Load the view file
          $data['css'] = $this->css;
          $data['base'] = $this->base;
          // set the header view
          $data['header'] = $this->load->view('header', '');
          // set the page content
          $data['content'] = $this->load->view('admin/content-success', $data);
          // set the footer view
          $data['footer'] = $this->load->view('footer', '');
        }

    }


/*======================================================================*\
    Function:    check_username($username)
    Purpose:    
    Input:        
    Output:        
\*======================================================================*/
    function check_username($username)
    {
        $this->load->helper('security');
        $password = dohash($this->input->post('password'));

        if ($this->erkanaauth->try_login(array('username' => $username, 'password' => $password)))
        {
            return TRUE;
        }
        else
        {
            $this->validation->set_message('check_username', 'Incorrect login info.');
            return FALSE;
        }
    }
    


/*======================================================================*\
                                  END
\*======================================================================*/
}

?&gt;

oops too long of a post will add more later....
#9

[eluser]zimco[/eluser]
POST CONTINUED....

Here's the code for my login view, content-sentry.php

Code:
<div id="content">

<div id="login">
<h1>Login</h1>

<div id="login_error">
&lt;?php echo $this->validation->error_string; ?&gt;
</div>

&lt;?php $attributes = array('id' => 'login'); ?&gt;

&lt;?php echo form_open('admin/sentry', $attributes); ?&gt;

<p>
&lt;?php
  echo form_label('Username: ', 'username');
  
  $username = array(
              'name'    => 'username',
              'maxlength'   => '10',
              'size'        => '25',
            );
  echo form_input($username);
  ?&gt;
</p>

<p>
&lt;?php
  echo form_label(' Password: ', 'username');
  $password = array(
              'name'    => 'password',
              'maxlength'   => '10',
              'size'        => '25',
            );
  echo form_password($password);
  ?&gt;
</p>
  
<div>&lt;input type="submit" value="Submit" /&gt;&lt;/div>

&lt;/form&gt;
  
</div>

</div>

Here's my code for Erkanaauth.php

Code:
&lt;?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

class Erkanaauth {

    var $CI;
    
    function Erkanaauth() {
        $this->CI =& get_instance();
        log_message('debug', 'Authorization class initialized.');
        
        $this->CI->load->database();
        $this->CI->load->library('session');
        $this->CI->load->library('encrypt');
        $this->CI->load->helper('erkanaauth_helper');
    }
    
    /**
     * Attempt to login using the given condition
     *
     * Accepts an associative array as input, containing login condition
     * Example: $this->auth->try_login(array('email'=>$email, 'password'=>dohash($password)))
     *
     * @access    public
     * @param    array    login conditions
     * @return    boolean
     */    
    function try_login($condition = array()) {
    
    $password = $condition['password'];
    //Salt the password see http://www.haughin.com/2008/02/17/handling-passwords-in-codeigniter/
    $condition['password'] = $this->_prep_password($password);
    
    $this->CI->db->select('id');
        $query = $this->CI->db->get_where('users', $condition, 1, 0);
        if ($query->num_rows != 1) {
            return FALSE;
        } else {
            $row = $query->row();
            $this->CI->session->set_userdata(array('user_id'=>$row->id));
            return TRUE;
        }
    }
    
    
    /**
     * Attempt to login using session stored information
     *
     * Example: $this->auth->try_session_login()
     *
     * @access    public
     * @return    boolean
     */
    function try_session_login() {
        if ($this->CI->session->userdata('user_id')) {
            $query = $this->CI->db->query('SELECT COUNT(*) AS total FROM users WHERE id = ' . $this->CI->session->userdata('user_id'));
            $row = $query->row();
            if ($row->total != 1) {
                // Bad session - kill it
                $this->logout();
                return FALSE;
            } else {
                return TRUE;
            }
        } else {
            return FALSE;
        }
    }
    
    
    /**
     * Logs a user out
     *
     * Example: $this->erkanaauth->logout()
     *
     * @access    public
     * @return    void
     */
     function logout() {
        $this->CI->session->set_userdata(array('user_id'=>FALSE));
    }
    
    
    /**
     * Returns a field from the user's table for the logged in user
     *
     * Example: $this->erkanaauth->getField('username')
     *
     * @access    public
     * @param    string    field to return
     * @return    string
     */
    function getField($field = '') {
        $this->CI->db->select($field);
        $query = $this->CI->db->get_where('users', array('id'=>$this->CI->session->userdata('user_id')), 1, 0);
      if ($query->num_rows() == 1) {
            $row = $query->row();
            return $row->$field;
        }
    }
    
    /**
     * Returns the user's role
     *
     * Example: $this->erkanaauth->getRole()
     *
     * @access    public
     * @return    string
     */
    function getRole() {
        $this->CI->db->select('roles.name');
        $this->CI->db->JOIN('roles', 'users.role_id = roles.id');
        $query = $this->CI->db->get_where('users', array('users.id'=>$this->CI->session->userdata('user_id')), 1, 0);
        if ($query->num_rows() == 1) {
            $row = $query->row();
            return $row->name;
        }
    }
    

/*======================================================================*\
    Function:  _prep_password($password)
    Purpose:   Salt the password with an encryption key
    Input:       password string
    Output:       password string plus encryption key
\*======================================================================*/    
function _prep_password($password)
{
     $mykey = sha1($password.$this->CI->config->item('encryption_key'));
     return $mykey;
}
    
/*======================================================================*\
                                  END
\*======================================================================*/    
}

?&gt;




Theme © iAndrew 2016 - Forum software by © MyBB