I am using the form validation functionality — it currently doesn't allow a user to enter incorrect username and password parameters when creating an account. But it's meant to bounce the user back to the signup screen. Instead they're brought through to the home screen, and if I use a username that's been used before it goes into the database anyway.
Signup controller:
class Signup extends CI_Controller {
function Signup() {
parent::__construct();
$this->load->model('membership');
}
function index() {
$this->load->view('shared/header');
$this->load->view('account/signuptitle');
$this->load->view('account/signupview');
$this->load->view('shared/footer');
}
function register() {
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'required|min_length[5]|max_length[12]|trim');
$this->form_validation->set_rules('password', 'Password', 'required|md5|trim');
$this->form_validation->set_rules('username', 'Username', 'callback_usernameTaken');
$username = $this->input->post('username');
$password = $this->input->post('password');
if ($this->form_validation->run()) {
$this->membership->newUser($username, $password);
$this->session->set_userdata('status', 'OK');
$this->session->set_userdata('username', $username);
redirect('home');
}
if ($this->membership->usernameTaken($username)) {
$this->load->view('shared/header');
$this->load->view('account/signuptitle');
$this->load->view('account/signupview');
$this->load->view('shared/footer');
} else {
$this->load->view('shared/header');
$this->load->view('account/signuptitle');
$this->load->view('account/signupview');
$this->load->view('shared/footer');
}
}
}
I think the if ($this->membership->usernameTaken($username)) statement needs to arranged a certain way could it possibly be an else if statement?
Membership Model:
class Membership extends CI_Model {
function Membership() {
parent::__construct();
}
function newUser($username, $password) {
$newMember = array('username' => $username,
'password' => $password);
$insert = $this->db->insert('membership', $newMember);
}
function usernameTaken($username) {
$this->db->select('*')->from('membership')->where('username', $username);
$query = $this->db->get();
if ($query->num_rows > 0) {
return true;
} else {
return false;
}
}
Thanks for the help again folks — I've been looking at similar issues on this site but I just found them too confusing
I'd say put those views in a template and you can load that template. It makes things look a bit neater.
Your index function should look like this
function index() {
$data['page_title'] = 'Sign up page';
$data['central_content'] = "sign_up";
$this->load->view('template');
}
In your template don't forget to load content, like thus;
<?php $this->load->view($central_content); ?>
Rearrange you register function to look like this;
function register() {
#you should be autoloading these helpers tbh
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'required|min_length[5]|max_length[12]|trim');
$this->form_validation->set_rules('password', 'Password', 'required|md5|trim');
$this->form_validation->set_rules('username', 'Username', 'callback_usernameTaken');
if ($this->form_validation->run()) {
$username = $this->input->post('username');
$password = $this->input->post('password');
#Learn to use flashdata, it helps.
if($this->membership->newUser($username, $password)){
$this->session->set_userdata('status', 'OK');
$this->session->set_userdata('username', $username);
redirect('home');
}
}else{
$this->index();
}
}
#You specified a callback but there's no callback function in your class? Here's how you go about it.
Public function usernameTaken(){
#callbacks should return true or false
if ($this->membership->usernameTaken($username)) {
return true;
} else {
#You can set your own validation message in the case it's false.
$this->form_validation->set_message('usernameTaken', 'The selected username already exists');
return false;
}
}
Your model is ok, try change the the funcs to this
function newUser($username, $password) {
$newMember = array('username' => $username,
'password' => $password);
return ($this->db->insert('membership', $newMember)) ? true : false;
}
function usernameTaken($username) {
#your query, requires a select * in a case where it's clearly not needed. Little things like this slow down your query.Try,
$query = $this->db->where('username', $username)->get('membership');
#Also num_rows()
return ($query->num_rows() > 0) ? false : true;
}
Just wrote this on here, so you'd have to test it out, but i'm sure it should be fine. Sorry i could't indent it properly though, it's a pain to do it on here :)
I believe when the register function runs, only this part of the code is executed before redirection.
if ($this->form_validation->run()) {
$this->membership->newUser($username, $password);
$this->session->set_userdata('status', 'OK');
$this->session->set_userdata('username', $username);
redirect('home');
}
try doing something like this.
if ($this->form_validation->run() && !$this->membership->usernameTaken($username)) {
$this->membership->newUser($username, $password);
$this->session->set_userdata('status', 'OK');
$this->session->set_userdata('username', $username);
redirect('home');
}
this way it wont redirect and proceed to execute lines below it.
The form validation probably doesn't have access to the model. Try moving usernameTaken($username) to the controller.
I think you are inserting every time.
if (! $this->membership->usernameTaken($username))
{
$this->membership->newUser($username, $password);
}
Related
I am working login and registration with codeigniter, registration works fine but login check is failing and can't able to find the solution.
Here is model and controller.
Model (User_model.php)
public function resolve_user_login($email, $password)
{
$this->db->select('password');
$this->db->from('user');
$this->db->where('email', $email);
$hash = $this->db->get()->row('password');
return $this->verify_password_hash($password, $hash);
}
private function verify_password_hash($password, $hash)
{
return password_verify($password, $hash);
}
Controller (User.php)
public function login()
{
$email = $this->input->post('email');
$password = $this->input->post('password');
$this->form_validation->set_rules('email', 'E-mail', 'required|valid_email');
$this->form_validation->set_rules('password', 'Password', 'required');
if ($this->form_validation->run() == FALSE)
{
$data['title'] = 'Login';
$this->load->view('default/header', $data);
$this->load->view('default/login');
$this->load->view('default/footer');
} else {
if ($this->User_model->resolve_user_login($email, $password))
{
echo 'Everything is good';
} else {
// error
$this->session->set_flashdata('msg','<div class="alert alert-danger text-center">Wrong e-mail or password</div>');
redirect('login');
}
}
}
private function hash_password($password)
{
return password_hash($password, PASSWORD_BCRYPT);
}
When i enter correct email and password it showing wrong email and password results.
Change your model function like this. Note that you do not need verify_password_hash() function anymore if you use below code.
public function resolve_user_login($email, $password)
{
$query = $this
->db
->where('email',$email)
->where('password',password_hash($password, PASSWORD_DEFAULT))
->limit(1)
->get('user');
if($query->num_rows()>0)
{
return $query->result();
}
else
{
return false;
}
}
and in controller a little change
if ($this->User_model->resolve_user_login($email, $password)!==False)
{
echo 'Everything is good';
}
Really hope this method work for you. If not specify errors in comments.
there is no way (yet) for decrypting hashes like bcyrpt or codeigenter's hash you can use php's method password_verify('your_word', 'the_hash' ); make a condition where if it returns true then you are able to login.
I have checked all questions of this type but none of them works for me. Hope I would get some help here. I have a controller named index and a model named Index_model. I have write user login and signup functions in the index controller and done data related queries in model everything is working fine except the codeigniter callback function.
When I try to validete user login details by using the callback each time it returns false and when I removed callback it is working fine. I am not getting where I am doing wrong. Please find the code below for my controller and model. Thanks in advance.
Controller:
class Index extends CI_Controller{
public function __construct(){
parent:: __construct();
$this->load->helper('url');
$this->load->model('index_model');
}
public function signin(){
$this->load->helper('form');
$data['title'] = "Sign In";
$data['headline'] = "Sign In";
$data['introduction'] = "Sign In to manage your business, clients and more!";
$data['include'] = "user/signin";
$this->load->view('template/template', $data);
}
public function login(){
$this->load->helper('url');
$this->load->helper('form');
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'required|callback_validate_login');
$this->form_validation->set_rules('password', 'Password', 'required|md5');
if($this->form_validation->run() == TRUE){
$data['msg'] = "User Login Successfully!!";
$this->load->view('user/home', $data);
}else{
$this->signin();
}
}
public function validate_login(){
$this->load->library('form_validation');
$result = $this->index_model->validate_user();
if($result == TRUE){
return TRUE;
}else{
$this->form_validation->set_message('validate_login', 'Incorrect username / password.');
return FALSE;
}
}
}
Model:
class Index_model extends CI_Model{
public function __construct(){
$this->load->database();
}
/******User Login*************/
public function validate_user(){
$username = $this->input->post('username');
$password = $this->input->post('password');
$this->db->where('username', $username);
$this->db->where('password', $password);
$query = $this->db->get('user');
if($query->num_rows() == 1){
return TRUE;
}else{
return FALSE;
}
}
}
Please, review My code it will be a great help.
You must get the parameter you are passing to the function using callback which is in this case the username. so change your code to this:
public function validate_login($username){ # get the parameter
$this->load->library('form_validation'); # you do not need this line here
$result = $this->index_model->validate_user($username); #chek the parameter
if($result == TRUE){
return TRUE;
}else{
$this->form_validation->set_message('validate_login', 'Incorrect username / password.');
return FALSE;
}
}
you should use
$this->db->where('password', md5($password));
/* you should use md5($password) instead of just $password since you are using md5 as hashing technique */
you have used
$this->form_validation->set_rules('password', 'Password', 'required|md5');
password gets converted to md5 after the validation is run and not in the callback process
$this->form_validation->run() //i.e. after this
Note : md5 is not at all secure now a days. beware of rainbow table attacks.
better change the hashing technique. there are a lot of questions regarding the password hashing & security in SO.
Just make few change in your code
$this->form_validation->set_rules('password', 'Password', 'required|md5');
remove md5 from here and add md5 function where your password matched your database table field
In validate_user function
$this->db->where('password', md5($password));
I have codeigniter installed on my localhost
The main.php controller is
class Main extends CI_Controller {
public function index()
{
$this -> login();
}
public function login()
{
$this->load->view('login');
}
public function login_validation() {
$this->load->library('form_validation');
$this->form_validation->set_rules('email','Email','required');
$this->form_validation->set_rules('password','Password','required|md5');
if($this->form_validation->run())
{
redirect('main/members');
}
else
{
$this->load->view('login');
}
}
}
The login is working page is coming,but after I fill the username and password,should take me to login/main/login_validation and from there the function login_validation() should either redirect to main/members or show me the login page.But what happens is when I submit the form,the object not found error is coming.Can anyone help me out?
form is
form_open('main/login_validation');
To answer what I think your question is getting at, you're using the form_validation class wrong. You should be testing whether or not the form_validation->run() is TRUE (all fields passed validation) or FALSE (there was an error in one or more of the inputs). Structure you code like such:
public function login_validation() {
$this->load->library('form_validation');
$this->form_validation->set_rules('email','Email','required');
$this->form_validation->set_rules('password','Password','required|md5');
if ($this->form_validation->run() === FALSE)
{
$this->load->view('login');
}
else
{
redirect('main/members');
}
}
This is covered in the CodeIgniter documentation here.
in your controller ..you could try this..
function index()
{
//This method will have the credentials validation
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'required');
$this->form_validation->set_rules('password', 'Password', 'required');
if($this->form_validation->run() == FALSE)
{
//Field validation failed. User redirected to login page
$this->load->view('login');
}
else
{
$this->check_database();
//redirect('home');
}
}
function check_database()
{
//Field validation succeeded. Validate against database
$username = $this->input->post('username');
$password = $this->input->post('password');
//query the database
$query_result = $this->model_login->login($username, $password);
if($query_result)
{
$this->load->view('main/members');
}
else
{
redirect('login');
}
}
in model
function login($username,$password){
$query = $this->db->query("SELECT * FROM `login` WHERE `username`= '".$username."' AND
password='".$password."' LIMIT 1");
if ($query->num_rows() > 0)
return TRUE;
else
return FALSE;
}
I drew out the logic for this feature on paper first so it made some sense where I was going with this. I have the form being created, the form calls a method in the control class on submit and then sent to the model for checking.
I belive the logic in my controller is correct, so the issue I think is with the method inside the model class.
function validate()
{
$this->db->where('username', $this->input->post('username'));
$this->db->where('password', $this->input->post('password'));
$query = $this->db->get('membership');
return $query;
}
I expected $query to return true or false, like a boolean would. Instead whatever its outputting appears to be true no matter if the inputted data matches that in the database or if its completely wrong. Below is the method in the controller class;
function validate_credentials()
{
$this->form_validation->set_rules('username', 'username', 'required');
$this->form_validation->set_rules('password', 'password', 'required');
if ($this->form_validation->run() == FALSE)
{
$this->createAdminForm();
}
else
{
$this->load->model('admin_Model');
$query = $this->admin_Model->validate();
if($query)
{
redirect('pages');
}
else // incorrect username or password
{
$this->createAdminForm();
}
}
}
I use different way, I think is more clear:
public function login(){
if($this->input->post('login')){
$this->form_validation->set_rules('username', 'Username', 'required|callback_valid_login');
$this->form_validation->set_rules('password', 'Password', 'required|callback_valid_password');
if($this->form_validation->run($this)){
$user = $this->user_model->get_by_field('username', $this->input->post('username'));
$this->session->set_userdata($user);
redirect("pages");
} else {
$this->load->view('login_failed');
}
} else
$this->load->view('login');
}
Found my own answer, changed the validate() method to this
function validate()
{
$this->db->where('username', $this->input->post('username'));
$this->db->where('password', $this->input->post('password'));
$query = $this->db->get('membership');
if($query->num_rows != 0)
{
$validate=true;
return $validate;
}
}
If a user does not exist its supposed to throw back an error on the login screen but the user is then brought to the home page as if they have previously registered in my sign controller. The login controller - validate credentials function - and my model - function can_log_in() - will illustrate the error its supposed to bounce back
model:
class Membership extends CI_Model
{
function Membership()
{
parent::__construct();
}
public function can_log_in()
{
$this->db->select('*')->from('membership');
$this->db->where('username', $this->input->post ('username'));
$this->db->where('password', md5($this->input->post ('password')));
$query = $this->db->get('membership');
if ($query->num_rows() == 1)
{
return true;
}
else{
return false;
}
}
login controller:
class Login extends CI_Controller
{
function Login()
{
parent::__construct();
$this->load->model('membership');
}
function loguserin()
{
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'required|min_length[5]|max_length[12]|trim');
$this->form_validation->set_rules('password', 'Password', 'required|md5|trim');
$username = $this->input->post('username');
$password = $this->input->post('password');
if ($this->form_validation->run()==TRUE)
{
$this->load->model('membership');
if($this->membership->can_log_in($this->input->post('username'),$this->input->post('password'))
{ // this is unepected despite a new if statement called
$this->session->set_userdata('status', 'OK');
$this->session->set_userdata('username', $username);
redirect('home');
} else //this else is unexpected
{
$this->session->set_userdata('status', 'NOT_OK');
$this->session->set_flashdata('Incorrect username/password');
$this->index();
}
} else {
$this->index;
}
}
function logout()
{
$this->session->sess_destroy();
redirect ('start');
}
function index()
{
$this->load->view('shared/header');
$this->load->view('account/logintitle');
$this->load->view('account/loginview');
$this->load->view('shared/footer');
}
}
Once again thanks :) its just that the user if not already in the table should not be able to sign into the home page
Your logic is all over the place and you're misunderstanding the concept of form validation. Form validation validates form input that's it, it does not validate credentials. The validate_credentials function you have is sort of pointless to be honest since you can't call the form validation error from outside the run function. So you may as well just make that go away entirely.
First, the initial call after form_validation should be like this:
if ($this->form_validation->run()==TRUE)
{
$this->load->model('membership');
if($this->membership->can_log_in($this->input->post('username'),$this->input->post('password')))
{
$this->session->set_userdata('status', 'OK');
$this->session->set_userdata('username', $username);
redirect('home');
} else {
$this->session->set_userdata('status', 'NOT_OK');// you'll need to do something
// here to tell them their credentials are wrong as I said this won't work through
// the form validation, perhaps look into using $this->session->set_flashdata()
$this->index();
}
} else {
$this->index; //reload the index to display the validation errors
Okay that takes care of sending the data to the login function, now the function actually needs to receive data, and since it is NOT the first page sent the data the post string will be empty, that is why I passed the data in the function above. The only part of the model that should need to change is the following:
public function can_log_in($username,$password)
{
$this->db->select('*')->from('membership');
$this->db->where('username', $username);
$this->db->where('password', md5($password));
try replacing
if ($this->form_validation->run())
with
if ($this->form_validation->run() && validate_credentials())