I have installed ion auth and everything is up and functional. The only problem I have is I want to change the login to use the visitors username instead of e-mail. I change the CONFIG option in the ion_auth.php config file and it still doesnt work. Is there an extra step Im missing??
ion_auth config
/**
* A database column which is used to
* login with.
**/
$config['identity'] = 'username';
login() in the controller
//log the user in
function login()
{
$this->data['title'] = "Login";
//validate form input
$this->form_validation->set_rules('email', 'E-mail Address', 'required|valid_email');
$this->form_validation->set_rules('password', 'Password', 'required');
if ($this->form_validation->run() == true)
{ //check to see if the user is logging in
//check for "remember me"
$remember = (bool) $this->input->post('remember');
if ($this->ion_auth->login($this->input->post('email'), $this->input->post('password'), $remember))
{ //if the login is successful
//redirect them back to the home page
$this->session->set_flashdata('message', $this->ion_auth->messages());
redirect($this->config->item('base_url'), 'refresh');
}
else
{ //if the login was un-successful
//redirect them back to the login page
$this->session->set_flashdata('message', $this->ion_auth->errors());
redirect('auth/login', 'refresh'); //use redirects instead of loading views for compatibility with MY_Controller libraries
}
}
else
{ //the user is not logging in so display the login page
//set the flash data error message if there is one
$this->data['message'] = (validation_errors()) ? validation_errors() : $this->session->flashdata('message');
$this->data['email'] = array('name' => 'email',
'id' => 'email',
'type' => 'text',
'value' => $this->form_validation->set_value('email'),
);
$this->data['password'] = array('name' => 'password',
'id' => 'password',
'type' => 'password',
);
$this->load->view('auth/login', $this->data);
}
}
login() model
public function login($identity, $password, $remember=FALSE)
{
if (empty($identity) || empty($password) || !$this->identity_check($identity))
{
return FALSE;
}
$query = $this->db->select($this->identity_column.', id, password, group_id')
->where($this->identity_column, $identity)
->where('active', 1)
->where($this->ion_auth->_extra_where)
->limit(1)
->get($this->tables['users']);
$result = $query->row();
if ($query->num_rows() == 1)
{
$password = $this->hash_password_db($identity, $password);
if ($result->password === $password)
{
$this->update_last_login($result->id);
$group_row = $this->db->select('name')->where('id', $result->group_id)->get($this->tables['groups'])->row();
$session_data = array(
$this->identity_column => $result->{$this->identity_column},
'id' => $result->id, //kept for backwards compatibility
'user_id' => $result->id, //everyone likes to overwrite id so we'll use user_id
'group_id' => $result->group_id,
'group' => $group_row->name
);
$this->session->set_userdata($session_data);
if ($remember && $this->config->item('remember_users', 'ion_auth'))
{
$this->remember_user($result->id);
}
return TRUE;
}
}
return FALSE;
}
Why are you still processing email in the controller (instead of username)?
You need to change your controller since it is still grabbing email from POST and using it to try to login.
You should add an index in the users table of username column
Related
I am working on a basic blog application in Codeigniter 3.1.8 and Bootstrap 4.
The application allows Registration and Login.
The passwords used to be encrypted with the md5() function:
$enc_password = md5($this->input->post('password'));
In the Login controller I had:
public function login() {
$this->form_validation->set_rules('email', 'Email', 'required|trim|valid_email');
$this->form_validation->set_rules('password', 'Password', 'required|trim');
$this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
if ($this->form_validation->run()) {
$email = $this->input->post('email');
$password = $this->input->post('password');
$this->load->model('Usermodel');
$current_user = $this->Usermodel->user_login($email, $password);
// If we find a user
if ($current_user) {
// If the user found is active
if ($current_user->active == 1) {
$this->session->set_userdata(
array(
'user_id' => $current_user->id,
'user_email' => $current_user->email,
'user_first_name' => $current_user->first_name,
'user_is_admin' => $current_user->is_admin,
'user_active' => $current_user->active,
'is_logged_in' => TRUE
)
);
// After login, display flash message
$this->session->set_flashdata('user_signin', 'You have signed in');
//and redirect to the posts page
redirect('/');
} else {
// If the user found is NOT active
$this->session->set_flashdata("login_failure_activation", "Your account has not been activated yet.");
redirect('login');
}
} else {
// If we do NOT find a user
$this->session->set_flashdata("login_failure_incorrect", "Incorrect email or password.");
redirect('login');
}
}
else {
$this->index();
}
}
and in the model:
public function user_login($email, $password) {
$query = $this->db->get_where('authors', ['email' => $email, 'password' => $hashed_password]);
return $query->row();
}
I had security concerns so I replaced md5() with password_hash() in the Register controller:
$enc_password = password_hash($this->input->post('password'), PASSWORD_DEFAULT);
Registration works fine, with a more secure password string in the database then before.
I have updated the user_login in the User model to:
public function user_login($email, $password) {
$query = $this->db->get_where('authors', ['email' => $email, 'password' => $hashed_password]);
return $query->row();
}
where $hashed_password comes from the Login controller:
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
This password matching, to my surprise, does not work.
What is the minimal amount of change in my login code that I must make for it to work?
I have matched user-supplied password against password_hash(), with minimal diferences between the two versions of the code, by modifying user_login() to:
public function user_login($email, $password) {
$pass_hash_query = $this->db
->select('password')
->get_where('authors', ['email' => $email]);
$pass_hash = $pass_hash_query->row()->password;
if (password_verify($password, $pass_hash)) {
$query = $this->db->get_where('authors', ['email' => $email, 'password' => $pass_hash]);
return $query->row();
}
}
In the Login controller I have:
public function login() {
$this->form_validation->set_rules('email', 'Email', 'required|trim|valid_email');
$this->form_validation->set_rules('password', 'Password', 'required|trim');
$this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
if ($this->form_validation->run()) {
$email = $this->input->post('email');
$password = $this->input->post('password');
$this->load->model('Usermodel');
$current_user = $this->Usermodel->user_login($email, $password);
// If we find a user
if ($current_user) {
// If the user found is active
if ($current_user->active == 1) {
$this->session->set_userdata(
array(
'user_id' => $current_user->id,
'user_email' => $current_user->email,
'user_first_name' => $current_user->first_name,
'user_is_admin' => $current_user->is_admin,
'user_active' => $current_user->active,
'is_logged_in' => TRUE
)
);
// After login, display flash message
$this->session->set_flashdata('user_signin', 'You have signed in');
//and redirect to the posts page
redirect('/');
} else {
// If the user found is NOT active
$this->session->set_flashdata("login_failure_activation", "Your account has not been activated yet.");
redirect('login');
}
} else {
// If we do NOT find a user
$this->session->set_flashdata("login_failure_incorrect", "Incorrect email or password.");
redirect('login');
}
}
else {
$this->index();
}
}
I hope this is useful to many people other than me.
You can not directly check the strings if password_hash is used. Because it gives different string every time.
In order to check equality of your password, you need to use password_verify method.
You can get the whole document here.
LINK BELOW:
securely-hash-passwords-with-php
I am trying to learn Codeigniter,I have the following code, it gives me "The page isn't redirecting properly..." error.
public function user_login_process() {
$this->form_validation->set_rules('username', 'Username', 'trim|required');
$this->form_validation->set_rules('password', 'Password', 'trim|required');
$classes['class'] = $this->show_classes();
$this->load->view('header');
if ($this->form_validation->run() == FALSE) {
if (isset($this->session->userdata['logged_in'])) {
$this->load->view('admin_page', $classes);
} else {
$this->load->view('login_form');
}
} else {
$data = array(
'username' => $this->input->post('username'),
'password' => $this->input->post('password')
);
$result = $this->login_database->login($data);
if ($result == TRUE) {
$username = $this->input->post('username');
$result = $this->login_database->read_user_information($username);
if ($result != false) {
$session_data = array(
'username' => $result[0]->user_name,
'email' => $result[0]->user_email,
);
$this->session->set_userdata('logged_in', $session_data);
$this->load->view('admin_page', $classes);
}
} else {
$data = array(
'error_message' => 'Invalid Username or Password'
);
$this->load->view('login_form', $data);
}
}
}
If I comment out this line
$this->load->view('header');
The page loads properly, without the header. But whenever I try to load header it fails. The problem is not with the header I believe as it loads properly on other pages.
Some context: I am trying to make an admin panel, there is a login page and a registration page and an admin page. This code segment handles the loading of admin page after successful login. Both the login and registration page loads the header file properly.
I looked into some related questions, but could not seem to find the correct solution to this issue, since I don't know what the actual issue is.
Any help is appreciated.
In your code, redirection and view file loading is not loading. Below I have written correct code with my comments where needed.
if (isset($this->session->userdata['logged_in'])) {
redirect(base_url('YOUR_AUTHORIZED_CONTROLLER_OR_FUNCTION'));
}
$this->form_validation->set_rules('username', 'Username', 'trim|required');
$this->form_validation->set_rules('password', 'Password', 'trim|required');
$classes['class'] = $this->show_classes();
$this->load->view('header');
if ($this->form_validation->run() == FALSE) {
// $this->session->userdata['logged_in'] this should not be used here. Instead you should validate your controller or methods for authorized area for logged in users
$this->load->view('login_form');
} else {
$data = array(
'username' => $this->input->post('username'),
'password' => $this->input->post('password')
);
$result = $this->login_database->login($data);
if ($result == TRUE) {
$username = $this->input->post('username');
$result = $this->login_database->read_user_information($username);
if ($result != false) {
$session_data = array(
'username' => $result[0]->user_name,
'email' => $result[0]->user_email,
);
$this->session->set_userdata('logged_in', $session_data);
// Commenting below line as you should redirect to your default authorised URL
//$this->load->view('admin_page', $classes);
$this->session->set_flashdata('success', 'Great! You have successfully logged in.');
redirect(base_url('YOUR_AUTHORIZED_DEFAULT_CONTROLLER_OR_FUNCTION'));
}
} else {
$this->session->set_flashdata('error', 'Invalid Username or Password');
// Redirect to login method and controller
redirect(base_url('LOGIN_ACTION'));
}
}
View:
In your view use below line to display error/success messages. It would be better to create new view file for displaying all messages in it and load this view just after header view loaded:
<?php echo $this->session->flashdata('error'); ?>
<?php echo $this->session->flashdata('success'); ?>
Let me know if you need any clarification.
I'm making a login system with 2 roles one for 'admin' and one for 'user'. I tried to make a else if statement for the login. This for the user login actually what happens now that every user is going to the admin_view right now.
In my database the row is called 'admin' which is a boolean so if the column 'admin' is 1 in the users table. The admin_view should be loaded if the value is 0 the user_view needs to be loaded.
I really don't know what to do now.
How do I need to seperate the roles between the admin and user?
Here is my controller: users.php
public function login() {
$this->form_validation->set_rules('username', 'Username', 'trim|required|min_length[3]');
$this->form_validation->set_rules('password', 'Password', 'trim|required|min_length[3]');
$this->form_validation->set_rules('confirm_password', 'Confirm Password', 'trim|required|min_length[3]|matches[password]');
if ($this->form_validation->run() == FALSE) {
$data = array(
'errors' => validation_errors()
);
$this->session->set_flashdata($data);
redirect('home');
} else {
$username = $this->input->post('username');
$password = $this->input->post('password');
$user_id = $this->user_model->login_user($username, $password);
if($user_id) {
$user_data = array(
'user_id' => $user_id,
'username' => $username,
'logged_in' => true
'admin' => 1;
);
$this->session->set_userdata($user_data);
$this->session->set_flashdata('login_success', 'You are now logged in');
$data['main_view'] = "admin_view";
$this->load->view('layouts/main', $data);
}
// Here I want the user_view to load op if the user haa a 0 value in
in the column admin.
else if($user_id) {
$user_data = array(
'user_id' => $user_id,
'username' => $username,
'logged_in' => true,
'admin' => 0;
);
$this->session->set_userdata($user_data);
$this->session->set_flashdata('login_success', 'You are now logged in');
$data['main_view'] = "user_view";
$this->load->view('layouts/main', $data);
} else {
$this->session->set_flashdata('login_failed', 'Sorry, you are not logged in');
redirect('home/index');
}
}
}
Here is my model: user_model.php
public function login_user($username, $password) {
$this->db->where('username', $username);
$result = $this->db->get('users');
$db_password = $result->row(2)->password;
$admin = $result->row(7)->admin;
if(password_verify($password, $db_password)) {
return $result->row(0)->id;
} else {
return false;
}
}
}
I apperciate the help.
First off, there is a typo in your array, the last one should not end with a ;.
In your user_model, instead of returning the ID, return some more information.
eg:
return $result->row(0);
Then, when you go back to your controller, you can do
$data = $this->user_model->login_user($username, $password);
array(
'user_id' => $data->id,
'username' => $username,
'logged_in' => true,
'admin' => $data->admin
);
From there, you could check in the session data whether admin is 0 or 1.
Then you can do :
if ($admin == 0) {
//send to wherever
} else {
//send some place else
}
Using codeigniter with ion_auth. On the login page, it appears that validation is not working; "if ($this->form_validation->run() == true)" is always returning false, but no error messages are displayed in the form. This is the straight out-of-the-box controller and view, I haven't edited anything. Not sure how to debug this; any ideas?
This is the function that is running, but not working:
function login()
{
$this->data['title'] = "Login";
//validate form input
$this->form_validation->set_rules('identity', 'Identity', 'required');
$this->form_validation->set_rules('password', 'Password', 'required');
if ($this->form_validation->run() == true)
{
// check to see if the user is logging in
// check for "remember me"
$remember = (bool) $this->input->post('remember');
if ($this->ion_auth->login($this->input->post('identity'), $this->input->post('password'), $remember))
{
//if the login is successful
//redirect them back to the home page
$this->session->set_flashdata('message', $this->ion_auth->messages());
redirect('/', 'refresh');
}
else
{
// if the login was un-successful
// redirect them back to the login page
$this->session->set_flashdata('message', $this->ion_auth->errors());
redirect('auth/login', 'refresh'); // use redirects instead of loading views for compatibility with MY_Controller libraries
}
}
else
{
// the user is not logging in so display the login page
// set the flash data error message if there is one
$this->data['message'] = (validation_errors()) ? validation_errors() : $this->session->flashdata('message');
$this->data['identity'] = array('name' => 'identity',
'id' => 'identity',
'type' => 'text',
'value' => $this->form_validation->set_value('identity'),
);
$this->data['password'] = array('name' => 'password',
'id' => 'password',
'type' => 'password',
);
$this->_render_page('auth/login', $this->data);
}
}
The page was posting to the wrong place. Duh.
I have this login php file from a CodeIgniter based PHP app. Basically I want to edit this so that if the user is member of "salesman" group then redirect them to another page. This will just be for this group others will redirect as normal and wont be effected.
Presume I need to add in an If at some part.
class Auth extends MX_Controller {
function __construct()
{
parent::__construct();
$this->load->library('ion_auth');
$this->load->library('session');
$this->load->library('form_validation');
$this->load->helper('url');
// Load MongoDB library instead of native db driver if required
$this->config->item('use_mongodb', 'ion_auth') ?
$this->load->library('mongo_db') :
$this->load->database();
}
//redirect if needed, otherwise display the user list
function index()
{
if (!$this->ion_auth->logged_in())
{
redirect('module=auth&view=login');
} else {
redirect('module=home');
}
}
function users() {
$groups = array('admin', 'purchaser', 'salesman', 'viewer');
if ($this->ion_auth->in_group($groups))
{
$this->session->set_flashdata('message', $this->lang->line("access_denied"));
$data['message'] = (validation_errors() ? validation_errors() : $this->session->flashdata('message'));
redirect('module=home', 'refresh');
}
$this->user_check();
$data['message'] = (validation_errors()) ? validation_errors() : $this->session->flashdata('message');
$data['success_message'] = $this->session->flashdata('success_message');
//list the users
$data['users'] = $this->ion_auth->users()->result();
foreach ($data['users'] as $k => $user)
{
$data['users'][$k]->groups = $this->ion_auth->get_users_groups($user->id)->result();
}
$meta['page_title'] = 'Users';
$this->load->view('commons/header', $meta);
$this->load->view('index', $data);
$this->load->view('commons/footer');
}
//log the user in
function login()
{
$data['title'] = "Login";
//validate form input
$this->form_validation->set_rules('identity', 'Identity', 'required');
$this->form_validation->set_rules('password', 'Password', 'required');
if ($this->form_validation->run() == true)
{ //check to see if the user is logging in
//check for "remember me"
$remember = (bool) $this->input->post('remember');
if ($this->ion_auth->login($this->input->post('identity'), $this->input->post('password'), $remember))
{ //if the login is successful
//redirect them back to the home page
$this->session->set_flashdata('success_message', $this->ion_auth->messages());
redirect('module=home', 'refresh');
}
else
{ //if the login was un-successful
//redirect them back to the login page
$this->session->set_flashdata('message', $this->ion_auth->errors());
redirect('module=auth&view=login', 'refresh'); //use redirects instead of loading views for compatibility with MY_Controller libraries
}
}
else
{ //the user is not logging in so display the login page
//set the flash data error message if there is one
$data['message'] = (validation_errors()) ? validation_errors() : $this->session->flashdata('message');
$data['success_message'] = $this->session->flashdata('success_message');
$data['identity'] = array('name' => 'identity',
'id' => 'identity',
'type' => 'text',
'value' => $this->form_validation->set_value('identity'),
);
$data['password'] = array('name' => 'password',
'id' => 'password',
'type' => 'password',
);
$this->load->view('auth/login', $data);
}
}
This condition will catch the logged in user's group and, if they are salesman, redirect them to to/whatever/page.
if ($this->ion_auth->in_group(array('salesman')))
redirect('to/whatever/page');
}