Should I compare $get value to stored relavent db value? - php

I am trying to implement resetting a users password in codeigniter.
I've created a form that the users sends their email and it creates a row in a 'reset' table that stores their token that is created as well as attaches the token the link sent to the email.
The final step is actually resetting the password. I am not understanding how to make the correct comparison when checking the token attached to the email against the one stored in the db associated with that email, or if that is even the right way to go about it.
In the current code I have, I am unable to get it to pass validation and actually reset the password. Here is my code:
This is the model for creating the token and sending the email:
public function validate_retrieve($data) {
$query = $this->db->where($data)->get('users', '1');
foreach ($query->result() as $user)
{
$user->email;
$user->salt;
$user->id;
}
$token = sha1($user->email.$user->salt).dechex($user->id);
$reset_token = array(
'token' => $token,
'email' => $user->email
);
$insert = $this->db->insert('reset', $reset_token, '1');
return $reset_token;
}
and the controller:
public function retrieve()
// REQUEST PASSWORD RESET
// LOADED WHEN THE FORM IS SUBMITTED OFF THE PASSWORD PAGE AND SENDS THE EMAIL WITH TOKEN AND INSTRUCTIONS
{
$this->load->library('form_validation');
$this->load->library('session');
$this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email');
$this->load->model('user_model', 'um');
$this->load->library('encrypt');
$this->load->helper('url');
$submit = $this->input->post('submit');
$salt = $this->_salt();
if($submit)
// IF THE SUBMIT BUTTON IS SET
{
// START PROCESS TO CREATE $USER VARIABLE THAT HOLDS WHAT THE USER ENTERED IN THE FORM AND THAT CAN GET CHECKED AGAINST THE DB IN THE MODEL
$user = $this->um->validate_retrieve(array('email' => $this->input->post('email')));
// IF THE USER IS CREATED AND CHECKS OUT AND ALL OF THE ERRORS ARE CLEARED ON THE FORM
if( $user && $this->form_validation->run() == TRUE ) {
$domain = "clci.dev/index.php";
// CREATE A TOKEN LINK TO SEND TO THE USERS EMAIL THAT EXIST IN THE DB AND WAS ENTERED
$token = $user['token'];
$link = "http://www.".$domain."/auth/reset/?token=$token";
$this->load->library('email');
$this->email->from('noreply#cysticlife.org', 'CysticLife');
$this->email->to($this->input->post('email'));
$this->email->subject('Reset Password');
$this->email->message("Please go to the following web address to reset your password:\n\n$link\n\n-Your friends at CysticLife\n\nPlease remember to add the cysticlife.org domain to your address book to ensure that you receive your CysticLife e-Notifications as requested.");
$this->email->send();
redirect('auth/success');
exit;
}
$this->form_validation->run() == FALSE;
$data['main_content'] = 'auth/password';
$this->load->view('includes/templates/main_page_template', $data);
$data['email_error'] = 'This email is invalid';
}
}
now here is what I'm having trouble with, the model for resetting:
public function verify_token($token)
{
$this->db->where('token', $token);
$query = $this->db->get('reset');
if ($query->num_rows() == 1) {
return TRUE;
} else {
return FALSE;
}
}
public function reset_password()
{
$salt = $this->_salt();
$query = $this->db->get('reset', 1);
$row = $query->row();
$data = array(
'password' => $this->encrypt->sha1($salt . $this->encrypt->sha1($this->input->post('password'))),
'salt' => $salt
);
$this->db->where('email', $row->email);
$this->db->update('users', $data);
}
and the controller:
public function reset_password()
{
$this->load->library('form_validation');
$this->load->library('session');
$this->load->model('user_model', 'um');
$this->load->library('encrypt');
$this->load->helper('url');
$this->form_validation->set_rules('password', 'Password', 'trim|required');
$this->form_validation->set_rules('password2', 'Confirm Password', 'trim|required|matches[password]');
$salt = $this->_salt();
$submit = $this->input->post('submit');
if($submit)
{
$validToken = $this->um->verify_token($token);
if($this->form_validation->run() == TRUE && $validToken == TRUE)
{
$this->um->reset_password(array('password' => $this->input->post('password', $salt)));
$data['main_content'] = 'auth/success';
$this->load->view('includes/templates/home_page_template', $data);
}
$this->form_validation->run() == FALSE;
$data['main_content'] = 'auth/reset';
$this->load->view('includes/templates/main_page_template', $data);
}
}
I seem to be very close but I am definitely stuck. Any help is greatly appreciated.

http://yoursitename.com/reset/[hashcode]
send the link to the member email, went password have reset by user.
on web site you will retrieve the hashcode to compare with your database
public function reset($hashcode)
{
if($hashcode!=null)
{
// compare with db
// if success
// redirect to create new password page
// or show create new password form
}
}

Related

Login in CodeIgniter with password_verify

I'm trying to achieve to login implementation in CodeIgniter, I'm hashing password while registration like password_hash($this->input->post('password'),PASSWORD_DEFAULT) in my Controller and in the same Controller I'm trying to write a login method which is as followed :
public function loginValidation() {
$this->form_validation->set_rules('email', 'Email', 'trim|required');
$this->form_validation->set_rules('password', 'Password', 'trim|required');
if ($this->form_validation->run()) {
// true
$email = $this->input->post('email');
$password = $this->input->post('password');
// User Model Loaded in constructor
if ($this->user->canLogin($email, $password)) {
$session_data = array('email' => $email );
$this->session->set_userdata($session_data);
redirect('profile/personal','Refresh');
} else {
$this->session->set_flashdata('error', 'Invalid Username or Password');
//redirect('login','Refresh');
}
} else {
// try again to login
//redirect('login','Refresh');
}
}
My user Model function is
public function canLogin($email, $password) {
$this->db->where('email',$email);
$this->db->where('password',$password);
$query = $this->db->get($this->tableName);
if ($query->num_rows() > 0) {
return true;
} else {
return false;
}
}
I know I have to password_verify($string,$hash) at some point but I'm unable to figure out.
How do I validate the password against email and redirect to the desired view i.e. personal/profile and I'm making request via AJAX call.
What you need to do is fetch the record from the DB where only the email matches (assuming it is the Unique key). Then you compare the returned value using password_verify().
This is very rough and untested, but should give you an idea:
public function canLogin($email, $password) {
$this->db->where('email',$email);
// $this->db->where('password',$password);
$query = $this->db->get($this->tableName);
$row = $query->row();
return $row ? password_verify($password, $row->password) : false;
}

Codeigniter Sessions not showing data

I have the following error in my code:
1) the data i am storing over session is not showing up in view
2) the form validation set rules is not working.. The required is not working. Whenever i press login without entering any field it prints a.
I have auto loaded session and form validation.
Should I use php sessions or ci sessions?
Controller:
public function loginFormValidation()
{
$this->form_validation->set_rules('email','Username','required'); //not working
$this->form_validation->set_rules('pass','Password','required');
$this->form_validation->set_error_delimiters('<div class = "text-danger">', '</div>');
if($this->form_validation->run())
{
$email = $this->input->post('email');
$pass = $this->input->post('pass');
$this->load->model('loginModel');
$result = $this->loginModel->loginValidation($email,$pass);
$user_id = $result->user_id;
$user_name = $result->user_name;
$password = $result->password;
$arrayDb = array(
'user_id' => $user_id,
'user_name' => $user_name,
'password' => $password,
);
$this->session->set_userdata('row', $arrayDb);
header("location:".base_url()."/Users/dashboard");
}
else
{
echo "a";
}
}
Model:
class loginModel extends CI_Model
{
public function loginValidation($email,$pass)
{
$q = $this->db->where(['email' => $email, 'password' => $pass])
->get('users');
if($q->num_rows())
{
return $q->row();
}
else
{
return false;
}
}
}
Controller where i am printing it for testing:
class Users extends CI_Controller
{
public function dashboard()
{
echo $this->session->userdata('user_name'); // Empty no data showing
exit;
}
}
Your code has a few errors and oversights.
You should NEVER store plaintext passwords, let alone add them to a session variable. There is no need for that. Check out: http://php.net/manual/en/function.password-verify.php
You need to check whether or not the login function actually returned data, otherwise just anyone can "login" as long as they pass form validation.
You are setting session data with an array incorrectly according to the way you want to access the variables.
Controller:
public function loginFormValidation() {
$this->form_validation->set_rules('email', 'Username', 'required');
$this->form_validation->set_rules('pass', 'Password', 'required');
$this->form_validation->set_error_delimiters('<div class = "text-danger">', '</div>');
if ($this->form_validation->run()) {
$email = $this->input->post('email');
$pass = $this->input->post('pass'); // do not store plaintext!!!
$this->load->model('loginModel');
$result = $this->loginModel->loginValidation($email, $pass);
if ($result) {
$user_id = $result->user_id;
$user_name = $result->user_name;
$password = $result->password;
//https://www.codeigniter.com/user_guide/libraries/sessions.html#adding-session-data
$arrayDb = array(
'user_id' => $user_id,
'user_name' => $user_name,
'password' => $password, // why are you storing their PLAINTEXT password in a session?!
);
$this->session->set_userdata($arrayDb);
header("location:" . base_url() . "/Users/dashboard");
} else {
echo 'login failed; bad username/password.';
}
} else {
echo validation_errors();
}
}
Model:
public function loginValidation($email, $pass) {
$q = $this->db->where(['email' => $email, 'password' => $pass])
->get('users');
if ($q->num_rows() == 1) {
return $q->row();
}
return false;
}
Rather than reinventing the wheel check out: https://github.com/benedmunds/CodeIgniter-Ion-Auth
I personally use it an recommend it.

passing user's details in Codeigniter using session [duplicate]

Hi guys I have a User controller and User_model model. I want to be able to retrieve and display a logged in users email and phone number from the database to a view after the user is logged in. any idea how I could go about this would be appreciated and if codes could be written to demonstrate I would be very happy.
MODEL
public function login($username, $password){
//validation
$this->db->select('id, email, username');
$this->db->where('username', $username);
$this->db->where('password', $password);
$this->db->where('status', 1);
$result = $this->db->get('users');
if($result->num_rows() == 1){
return $result->row(0)->id;
} else {
return FALSE;
}
}
public function get_user($username){
$this->db->where('username', $username);
$query = $this->db->get('users');
return $query->result();
}
CONTROLLER:
public function login(){
$data['title'] = 'Login';
$this->form_validation-> set_rules('username', 'Username', 'required');
$this->form_validation-> set_rules('password', 'Password', 'required');
if($this->form_validation->run() === FALSE){
$this->load->view('templates/header');
$this->load->view('users/login', $data);
$this->load->view('templates/footer');
} else {
// fetching user
$username = $this->input->post('username');
//Encrypted password
$password = md5($this->input->post('password'));
//login user
$user_id = $this->user_model->login($username, $password);
if($user_id){
//creating session
$user_data = array(
'user_id' => $user_id,
'username' => $username,
'logged_in' => TRUE,
);
$this->session->set_userdata('user_data',$user_data);
// Set message to be sent
$this->session->set_flashdata('user_login', 'Welcome');
redirect('posts');
} else {
// Set message to be sent
$this->session->set_flashdata('login_fail', 'Login Failed');
redirect('users/login');
}
}
}
public function get_user()
{
if($this->session->userdata('logged_in')){
$username = $this->session->userdata('username');
$data['results'] = $this->user_model->get_user($username);
$this->load->view('templates/header');
$this->load->view('users/login', $data);
$this->load->view('templates/footer');
}
}
There is basic problem in your Controller
Session Data Problem: In your Controller you storing all array data in CodeIgniter Session:
the 'user_data' would work like array key, and all other array will be assign as keys data;
$this->session->set_userdata('user_data', $user_data);
and you retrieving/checking the session data by using $this->session->userdata('logged_in') and $this->session->userdata('username'), It's wrong my friend. You can get user data session by $this->session->userdata('user_data')['username'] or $this->session->userdata['user_data']['username'] ...
Because the session would be like;
Array
(
[__ci_last_regenerate] => 1499791562
// This is the array key 'user_data' where your array data stores
[user_data] => Array
(
[user_id] => 1
[username] => scott
[email] => scott.dimon#example.com
[phone_number] => 1234567890
[first_name] => Scott
[logged_in] => 1
)
)
So, you have to have use 'user_data' with session to get your data
One thing I would like to share with everyone, Always Read The Docs and manual Carefully. Believe me if you read before the start, your code would be more nicer and cleaner... Ha ha ha ha ha.. ;) :|
When you login if you set the users_id in session you can get the information like
Read manual also
https://www.codeigniter.com/user_guide/database/results.html#result-rows
https://www.codeigniter.com/user_guide/general/views.html#adding-dynamic-data-to-the-view
Make sure you autoload session, and database.
Examples ONLY below.
Filename: User_model.php
class User_model extends CI_Model {
public function get_user($id)
{
$this->db->where('user_id', $id);
$user_query = $this->db->get('yourtable');
return $user_query->row_array();
}
}
Filename: Dashboard.php
Controller
<?php
class Dashboard extends CI_Controller {
public function __construct()
{
parent::__construct();
if (!$this->session->userdata('user_id'))
{
redirect('logoutcontroller');
}
$this->load->model('user_model');
}
public function index()
{
$userdata = $this->user_model->get_user($this->session->userdata('user_id'));
/** You can use what you want example
$data['email'] = $userdata['email'];
**/
$data['username'] = $userdata['username'];
$this->load->view('some_view', $data);
}
}
View
<?php echo $username;?>
You can use session to carry the logged in user detail.
This is your model code:
//In your model
$query = $this->db
->select('id,email,phone')
->where(['username' => $username, 'password' => $password])
->where('status','1')
->get('users');
$user_data = $query->row_array();
if (!empty($user_data)) {
return $user_data;
} else {
return FALSE;
}
In side the controller where you get the user data if username & password is correct. Here you can put the user data on session:
//In Side Controller
$user_data = $this->user_model->login($username, $password);
if(isset($user_data) && !empty($user_data)){
// you can directly add the `$user_data` to the session as given billow.
// set user data in session
$this->session->set_userdata('user_data', $user_data);
Now after putting a data on session you can retrive it any where, on any view or in side morel, controller.
//retrive the user data in any view
//To echo in view Inside your view code.
<?php
$session_data = $this->session->userdata('user_data');
$user_email = $session_data['email'];
$user_phone = $session_data['phone'];
$user_id = $session_data['id'];
?>
<?= $user_phone ?> OR <?php echo $user_phone; ?>
<?= $user_email ?> OR <?php echo $user_email; ?>
On Your $this->load->view('users/login', $data); this view. Where the HTML & PHP code placed.
Example:
<html>
// Your View Page
</body>
<?php
$session_data = $this->session->userdata('user_data');
$user_email = $session_data['email'];
$user_phone = $session_data['phone'];
$user_id = $session_data['id'];
?>
<h1> Logged In User Email: <?= $user_email ?> </h1>
<h1> Logged In User Phone: <?= $user_phone ?> </h1>
<body>
</html>
Note: Once You save the user data inside the session then you don't need to pass that data to the view form controller. You just need to echo it where you need that.
You need to load session library first. like
$this->load->library('session');
Then after you can save your data into session like,
$newdata = array(
'username' => 'johndoe',
'email' => 'johndoe#some-site.com',
'logged_in' => TRUE
);
$this->session->set_userdata($newdata);
Then where ever you require at controller you can retrive session data like,
$data['session_data'] = $this->session->all_userdata();
and then pass to your view,
$this->load->view('data', $data);
and then access that data into your view with the key,
<?= $session_data['username']; ?>
I hope it helps,
Does this answer your question?
public function login($username, $password){
$db = $this->db;
//validation
$db->select('id, email, username');
$db->where('username', $username);
$db->where('password', $password);
$db->where('status', 1);
$result = $db->get('users')->row_array();
return empty($result['id']) ? false : $result['id'];
}
With a unique index on username you won't need to check the number of rows as it will be limited to 1.
if($user_id){
//creating session
$user_data = array(
'user_id' => $user_id,
'username' => $username,
'logged_in' => TRUE,
);
$this->session->set_userdata($user_data);
// Set message to be sent
$data['session_data'] = $this->session->all_userdata();
$this->session->set_flashdata('user_login', 'Welcome');
$this->load->view('posts', $data);
//redirect('posts');
}
else {
// Set message to be sent
$this->session->set_flashdata('login_fail', 'Login Failed');
redirect('users/login');
}
}
at the view,
<?php print_r($session_data); ?>
if you get your session data into print,
you can display it like,
<?= $session_data['user_id']; ?>
****Modal**
//user login**
function userlogin($data)
{
$condition = "username =" . "'" . $data['username'] . "' AND " . "password =" . "'" . $data['password'] . "' AND " . "status = '1'";
$this->db->select("*");
$this->db->from("user");
$this->db->where($condition);
$this->db->limit(1);
$query = $this->db->get();
if ($query->num_rows() == 1)
{
return $query->result();
}
else {
return false;
}
}
And in your Controller check
if($this->modal_name->login()==false)
{
//redirect user to login page
}
else
{
$data['details'] = $this->modal_name->login();
$this->load->view("post",$data);
}
View
foreach($details as $detail)
{
echo $detail->id;
echo $detail->username;
}

How do I pull a variable from a model to use on my controller in CodeIgniter?

I am trying to use a variable in my controller that has been created in my model.
Here is the model:
public function validate_retrieve($data) {
$query = $this->db->where($data)->get('users', '1');
foreach ($query->result() as $user)
{
$user->email;
$user->salt;
$user->id;
}
$token = sha1($user->email.$user->salt).dechex($user->id);
$reset_token = array(
'token' => $token,
'email' => $user->email
);
$insert = $this->db->insert('reset', $reset_token, '1');
return $reset_token;
}
and on my controller I'm trying to use $token that was created in the model:
public function retrieve()
// REQUEST PASSWORD RESET
// LOADED WHEN THE FORM IS SUBMITTED OFF THE PASSWORD PAGE AND SENDS THE EMAIL WITH TOKEN AND INSTRUCTIONS
{
$this->load->library('form_validation');
$this->load->library('session');
$this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email');
$this->load->model('user_model', 'um');
$this->load->library('encrypt');
$this->load->helper('url');
$submit = $this->input->post('submit');
$salt = $this->_salt();
if($submit)
// IF THE SUBMIT BUTTON IS SET
{
// START PROCESS TO CREATE $USER VARIABLE THAT HOLDS WHAT THE USER ENTERED IN THE FORM AND THAT CAN GET CHECKED AGAINST THE DB IN THE MODEL
$user = $this->um->validate_retrieve(array('email' => $this->input->post('email')));
// IF THE USER IS CREATED AND CHECKS OUT AND ALL OF THE ERRORS ARE CLEARED ON THE FORM
if( $user && $this->form_validation->run() == TRUE ) {
$domain = "clci.dev/index.php";
// CREATE A TOKEN LINK TO SEND TO THE USERS EMAIL THAT EXIST IN THE DB AND WAS ENTERED
$token = $this->um->token;
$link = "http://www.".$domain."/auth/reset/?token=$token";
$this->load->library('email');
$this->email->from('noreply#cysticlife.org', 'CysticLife');
$this->email->to($this->input->post('email'));
$this->email->subject('Reset Password');
$this->email->message("Please go to the following web address to reset your password:\n\n$link\n\n-Your friends at CysticLife\n\nPlease remember to add the cysticlife.org domain to your address book to ensure that you receive your CysticLife e-Notifications as requested.");
$this->email->send();
redirect('auth/success');
exit;
}
$this->form_validation->run() == FALSE;
$data['main_content'] = 'auth/password';
$this->load->view('includes/templates/main_page_template', $data);
$data['email_error'] = 'This email is invalid';
}
}
thanks in advance
You're trying to access an array as an object.
$reset_token = $this->um->validate_retrieve($whatever_id);
$token = $reset_token['token'];
That's how you access the token portion of the returned results from this function.
And according to your latest update, you would actually access it like this:
$token = $user['token'];
Because in the following line you assign the results of the validate_retrieve method to the variable $user:
$user = $this->um->validate_retrieve(array('email' => $this->input->post('email')));

hashing/salting post data codeigniter

I am at the tail end of signing in a created user to an account. I've commented out my flow and everything seems to make since, however I am missing a step or two because now the post data password is not being hashed.
CONTROLLER:
function validate_credentials()
{
// WHEN THE VIEW IS LOADED THIS FUNCTION IS CALLED AND LOADS MODEL AS WELL AS DEFINES THE SALT VARIABLE AND LOADS THE ENCRYPTING HELPER LIBRARY
$this->load->model('user_model', 'um');
$login = $this->input->post('submit');
$salt = $this->_salt();
$this->load->library('encrypt');
//IF THE SUBMIT BUTTON IS TRIGGERED THE POST DATA IS SENT TO THE VALIDATE FUNCTION IN THE MODEL VIA VARIABLES CREATED
if($login)
{
$data = array(
'email' => $this->input->post('email'),
'password' => $this->encrypt->sha1($user->salt. $this->encrypt->sha1($this->input->post('password')))
);
$user = $this->um->validate($data);
}
// IF ITS A REAL USER OPEN THE GATE AND LET THEM IN
if($user)
{
$this->session->set_userdata($data);
redirect('account/dashboard');
}
else
{
$this->index();
}
}
MODEL:
function validate($data)
{
$this->output->enable_profiler(TRUE);
// TAKING THE DATA FROM THE MODEL AND CHECKING IT AGAINST THE STORED INFO IN THE DB
$query = $this->db->where($data)->get('users', 1);
if($query->row())
{
return $query->row();
}
}
thanks in advance
$user->salt should just be $salt.

Categories