Callback function in Codeigniter with multiple parameters during form validation - php

In Codeigniter:
Here is the callback function that I am using for validation:
public function has_match($password, $username){
if (0) {
// user exists
return true;
}
else {
$this->form_validation->set_message('has_match', 'Invalid Username/password entered ' . $password . ' ' . $username);
return false;
}
}
Below are the validation rules:
$this->form_validation->set_rules('username', 'Username', 'required');
$this->form_validation->set_rules('password', 'Password', 'required|callback_has_match[username]');
Can any one please tell me what I am doing wrong here in calling the callback function, as I am unable to get the value of the username field and it keeps showing 'username' (inside the variable $username in callback) instead?

Your code is working as expected. You're basically always calling the callback method has_match with the string username as a parameter. I think that you expect that this translates into:
callback_has_match[$username]
Therefore, when you access the has_match() method, you would have access to the value of $username. This is however, not the way callback methods work. The parameter that you set in there is a string, which is hardcoded, exactly like you do when you add a rule for min_length[10] - it's not the value of a PHP variable. An easy fix, which I haven't tested but suspect works is to do:
$this->form_validation->set_rules('password', 'Password', 'required|callback_has_match[' . $username . ']');
However the code above is not clean, and seems bad design in my opinion.
Now that we've found the problem with the code, I know it's outside the scope of the question, but I would like to point it out - I find it's more of a design issue here. Why do you want to check for the username/password pair inside of a callback to the password field?
Remember, you're validating a form, you shouldn't mix it up with model work. The form doesn't care if the provided username/password combo is correct, it should just look at whether both the fields have been provided correctly, and if so, it should do something about it.
I would adapt your code above to:
$this->form_validation->set_rules('username', 'Username', 'required');
$this->form_validation->set_rules('password', 'Password', 'required|callback_has_match[username]');
if ($this->form_validation->run() != FALSE) {
$validLogin = $this->muser->checkLogin($username, $password);
if ($validLogin) {
//Username/password combo exists in DB, save in session or whatever.
} else {
//Username/password combo does not exist in DB, show an error.
}
} else {
//Code for when form fields have not been provided correctly.
}

Instead of sending parameters with call back you can always get them with post
Here is your call back
public function has_match(){
if (0) {
// user exists
return true;
}
else {
$password = $this->input->post('password');
$username = $this->input->post('username');
$this->form_validation->set_message('has_match', 'Invalid Username/password entered ' . $password . ' ' . $username);
return false;
}
}

// CALLBACKS
public function check_user(){
$result = FALSE;
$username=$this->input->post('username');
$email=$this->input->post('emailad');
$dbmember=$this->members->get_members();
foreach ( $dbmember as $key){
// condition of username and email
if($username==$key && $email==$key){
if($username == $key->UserName && $email == $key->EmailAddress){
$this->form_validation->set_message('check_user','already existed!
Please check username and email agian.');
return FALSE;
break;
}
return TRUE;
}
}

Related

Trying to get property of non-object when username is incorrect using CodeIgniter

I am using password_verify to check the password is correct or not which is working perfectly. My issue is when the user entered the wrong username clicked on login button than I am getting the error that "Trying to get property of non-object".
Instated of error it should display the validation error message.
If I enter the correct username and wrong password than I am getting the proper validation error message(Password is invalid) but If I enter the wrong username and correct password then I am getting the error "Trying to get property of non-object".`
Would you help me out in this?
Controller
public function login_user()
{
$this->form_validation->set_error_delimiters('', '');
$this->form_validation->set_rules('user_email', 'Email', 'trim|required|valid_email');
$this->form_validation->set_rules('user_password', 'Password', 'trim|required|xss_clean|callback_check_password_database');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('login');
}
else
{
//redirect(base_url('Student_controller/index'),'refresh');
}
}
/*Checking the login details*/
function check_password_database($user_password)
{
$a_username=$this->input->post('user_email');
if (empty($a_username)) {
$this->form_validation->set_message('check_password_database','Email is Invalid');
}
else{
$password_fetch=$this->access_model->password_fetch($a_username);
if(password_verify($user_password, $password_fetch))
{
redirect('Student_controller/index','refresh');
}
else{
$this->form_validation->set_message('check_password_database','Password is Invalid');
return FALSE;
}
}
}
Model
public function password_fetch($username)
{
$query=$this->db->select('emp_password')
->from('employee_info')
->where('emp_email',$username)
->get();
$result = $query->row();
return $fetch_pass=$result->emp_password;
}
You are doing
return $fetch_pass = $result->emp_password;
without validating if $result is actually an object. If the user does not exist, the $result will not be an object. Consequently, trying to fetch emp_password when $result is not an object, will give you the error message Trying to get property of non-object.
Do this instead:
if (isset($row)) {
return $result->emp_password;
}
Further reference: https://www.codeigniter.com/userguide3/database/results.html
On a side note, an application should respond with a generic error message regardless of whether the user ID or password was incorrect. It should also give no indication to the status of an existing account.
Change your model
public function password_fetch($username)
{
$fetch_pass = false;
$query=$this->db->select('emp_password')
->from('employee_info')
->where('emp_email',$username)
->get();
$result = $query->row();
if (isset($row) && ($row > 0)) {
$fetch_pass=$result->emp_password;
}
return $fetch_pass;
}
You must be trying to access an array directly. Between $a_username and $password_fetch one must be a array which you are directly trying to access.
You must echo both of them to find how values are stored in them.Try printing them with echo $a_username;die; and similarly for the other.
If it is an array try printing echo "<pre>";print_r$(a_username);
Also initialize $fetch_pass="" in model;

Same password values comparison returns false cakephp

I am trying to compare the input 'pass' with the 'pass' from the database. If it matches, the user will then proceed to the registration form.
Even though both passwords have the same value, I still get a false result with 'password is not correct' and a notice: Undifined index:pass.
I'm using Cakephp 2.8
This is the code I have now:
public function checkCodeRespondent() {
$password = $this->data['Respondent']['pass'];
if (isset($password) && !empty($password))
{
$respondent = $this->findByPass($password);
debug($respondent);
if ($this->data['Respondent']['pass'] != $respondent['pass']) {
print 'password is not correct';
} else {
print 'password is correct';
}
}
And this is the function to retrieve the data from database
public function findByPass($pass) {
$respondent = $this->Respondent->find('first', array('conditions' => array('pass' => $pass)));
return $respondent;
}
If your password is not hashed just try :
public function checkCodeRespondent() {
$password = $this->data['Respondent']['pass'];
$condition = array('Respondent.pass'=>$password);
if($this->Respondent->hasAny($condition)){
print 'password is correct';
} else {
print 'password is not correct';
}
}
You don't need multiple function at all..
Undefined index 'pass'
means an array is referencing a Key value that has not been set, so either $this->data['Respondent']['pass'] value has not been set or $respondent['pass'] has not been set. Check both and see which one is missing and then step back to find the cause of the missing data.
Debug:
What does a print_r($this->data); output? And what does print_r($respondent); output, are both of these arrays the shape you expect?
NB: Also because they're passwords:
Are either of these values hashed? If so, are both of them hashed?
I made a typo :)
This:
if ($this->data['Respondent']['pass'] != $respondent['pass'])
Should be this:
if ($this->data['Respondent']['pass'] != $respondent['Respondent']['pass'])
Now the comparison works like a charm

How can I assign a variable to a query in codeigniter

For my project I need to check if some variables are empty and if they are then:
The user gets a custom view with a message on which variable is missing.
The developer/me must be able to see the query which was sent to check if there are no failure's in the query.
My question is how can I assign a variable (for example $checkQuery) to my query so that it has all the values and I can check it within the error log.
Query
function createUser($data){
$this->firstname = $data['firstname'];
$this->lastname = $data['surname1'].' '.$data['surname2'];
$this->address = $data['adres'];
$this->zipcode = $data['zipcode'];
$this->mail = $data['mail'];
$this->phonenumber = $data['phonenumber'];
$this->db->insert('User',$this);
//Check if the change was succesfull
return ($this->db->affected_rows() != 1) ? false : true;
}
Function for errorLog
function errorLog($var){ //Get the variable that you have passed from your helper
$mail = "Email was empty";
$firstname ="Firstname was empty";
if($var == 'mail') //Change the error function based on what has been passed
{
return log_message('error', $mail); //Here use the return type
}
if($var == 'firstname')
{
return log_message('error', $firstname); //Here use the return type
}
}
The view for the user is done which I've done with just a simple array but the only thing I see at the moment is just if firstname or email is was empty.
So is it possible to use a PHP variable in which I can assign the submitted values and can put these into my error log preferably using log_message

Result returns 0 on password hash validation

I'm in the process of learning how to use the CI framework and am currently working on a user login form. Haven't created a user registration yet, so I'm manually adding credentials into the database. Since I'm testing everything locally, I decided to give crypt a try with no salt which is probably not the best method. I'm using form validation and a callback to check the form data against the information in the database.
here is a snippet from the users controller:
function password_check($password) {
$username = $this->input->post('username', TRUE);
$password = Modules::run('security/create_hash', $password);
$this->load->model('mdl_users');
$result = $this->mdl_users->password_check($username, $password);
if ($result == FALSE) {
//$this->form_validation->set_message('password_check', 'Please login using the correct credentials!');
//return FALSE;
echo $password;
echo '<br/><br/>';
echo $result;
echo '<br/><br/>';
}
else {
return TRUE;
}
}
I echoed the password and the result for testing and password is showing as hashed.
Here is the password_check method:
function password_check($username, $password) {
$table = $this->get_table();
$this->db->where('username', $username);
$this->db->where('password', $password);
$query=$this->db->get($table);
$num_rows = $query->num_rows();
return $num_rows;
if ($num_rows>0) {
return TRUE;
} else {
return FALSE;
}
}
I'm sure the reason this isn't working is because the password in the DB is being treated as a literal string and not as hashed, but I'm not sure as to how I can compare it as a hash.
You could do something like this: get the user from the model and then check the saved value from the password with the hashed value from the user. If you would use md5 it would look a bit like this.
controller
$this->load->model('user_model');
public function login() {
$name = $this->input->post('name');
$password = $this->input->post('password');
$user = $this->user_model->get_user_through_name($name);
if($user['password'] == md5($password)) {
//logged in
} else {
//wrong password
}
}
model
public function get_user_through_name($name) {
$query = $this->db->get_where('Users', array(
'username' => $name
));
return $query->row_array();
}

Fatal error: Call to a member function login() on a non-object in

Got an issue with a web app that I've inherited as a project and unfortunately I can't trace the error. It seems that the model isn't being loaded but I could be wrong. Any help would be great.
code is:
public function login()
{
//If request is post then user is trying to login, so process the login info
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
//Run the model method ::login
$login_successful = $this->User->login();
// check login status
if($login_successful) {
// if YES, then move user to dashboard/index (btw this is a browser-redirection, not a rendered view!)
header('location: ' . URL . 'passwords/index');
} else {
echo "Incorrect user / pass combination entered. Please try again.";
}
}
}
and the model function is:
public function login() {
$username = $_POST['data']['User']['username'];
$password = $_POST['data']['User']['password'];
$bind = array(
":username" => "$username",
);
$result = $this->select("users", "username = :username", $bind);
//Check the password returned from the db against the password entered
if (Bcrypt::checkPassword($password, $result[0]['password']) == true) {
Session::init();
Session::set('user_logged_in', true);
Session::set('user_id', $result[0]['id']);
Session::set('user_name', $result[0]['username']);
Session::set('user_permission', $result[0]['permission']);
Session::set('user_role', $result[0]['role']);
return true;
} else {
return false;
}
}
also I've noticed that the controller and model both have a function called login.]
Thanks
The reason is $this->User is not a valid class instance.
Make sure that it is an object.
Try
var_dump($this->User);
die();
//Run the model method ::login
$login_successful = $this->User->login();
And you will see that there is no instance there.
What to do?
Find the place where you expect your model being initialized. Check, why it is not.

Categories