Hi I would like to add here a case sensitive error trap on my login function, by the way i am using MVC FRAMEWORK anyone be of help ? I want to make the username and password case sensitive so that is the input doesn't match an error exception will occur............... I have tried but failed maybe someone can assist me on hot to go about this dilemma
//THIS IS THE CODE OF MY CONTROLLER
public function login() {
if(isLoggedIn()) {
header("Location: " .URLROOT . "/");
}
$data = [
'title' => 'Login page',
'username' => '',
'password' => '',
'usernameError' => '',
'passwordError' => ''
];
//Check for post
if($_SERVER['REQUEST_METHOD'] == 'POST'){
//Sanitize post data
$_POST = filter_input_array(INPUT_POST);
$data = [
'username' => trim($_POST['username']),
'password' => trim($_POST['password']),
'usernameError' => '',
'passwordError' => '',
];
$findUser = $this->userModel->findUser($data);
//Validate username
if(empty($data['username'])){
$data['usernameError'] = 'Please enter a username.';
}else if($findUser === false){
$data['usernameError'] = "Username not registered";
}
//Validate username
if(empty($data['password'])){
$data['passwordError'] = 'Please enter a password.';
}else if($findUser === false){
$data['passwordError'] = "Password not registered";
}
$findUser = $this->userModel->getUserDetails($data);
//Check if all errors are empty
if(empty($data['usernameError']) && empty($data['passwordError'])){
$loggedInUser = $this->userModel->login($data['username'], $data['password']);
if($loggedInUser){
$this->createUserSession($loggedInUser);
}else {
$data['passwordError'] = 'Password is incorrect. Please try again.';
$this->view('users/login',$data);
}
}
}else{
$data = [
'username' => '',
'password' => '',
'usernameError' => '',
'passwordError' => ''
];
}
//THIS IS THE CODE OF MY MODEL
public function login($username, $password) {
$this->db->query('SELECT * FROM user WHERE username = :username');
//Bind value
$this->db->bind(':username', $username);
$row = $this->db->single();
$hashedPassword = !empty($row) ? $row->password:'';
if(password_verify($password, $hashedPassword)){
return $row;
}else {
return false;
}
}
$this->view('users/login', $data);
}
Case sensitive error trap
If you need to make a case-sensitive query, it is very easy to do using the BINARY operator, which forces a byte by byte comparison:
SELECT * FROM `table` WHERE BINARY `column` = 'value'
The password is already case-sensitive, since it's using the native password_hash and password_verify functions, it can be easily tested with:
var_dump(password_verify('AAA', password_hash('AAA', PASSWORD_DEFAULT))); // true
var_dump(password_verify('AAA', password_hash('aaa', PASSWORD_DEFAULT))); // false
If you really want to have the username case-sensitive, you can also use a case-sensitive collation for the username field, such as utf8mb4_0900_as_cs, more info here.
ALTER TABLE `users` CHANGE COLUMN `username` `username` VARCHAR(255) CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_0900_as_cs' NOT NULL;
Test case:
INSERT INTO `users` (`username`) VALUES ('test');
SELECT * FROM `users` WHERE `username`='TEST'; /* returns nothing as expected */
Related
i have 3 tables within my db: users, lots and auction
lots contains lotid, title, desc, photo, and fk a_id and this table is products and links to auction through a_id as that shows whos selling product
auction contains a_id,name, address and date. this table is basically the seller info
users contains all information related to logging in and out
currently on my website you can register login and logout without anyissues now im trying to add a search onto the page so you can search for items that are listed and it should return the output showing all fields from lotid and also show the auction data so the data returned is like this
the db has a few records for now but will be populated with around 500 lot records and 50 auction records so the search needs to be able to go through this and only return relevant information the search criteria should be for example: theres 100 types of phone if i search "phone" it should show iphones aswell as anything else that contains phone within the title so red phone would return aswell. but currently im really struggling and have massive errors im new to using mvc so it could be im using the wrong files like views models etc but my log in system works fine so i need help adding this search function as currently its like this when i tested it here is my directories i currently tried this search function by adding the search form to the auction.php page and using the users.php controller although i may need new controller for this page
code for auction.php
<?php
require APPROOT . '/views/includes/head.php';
?>
<div class="navbar">
<?php
require APPROOT . '/views/includes/navigation.php';
?>
</div>
<form action="search.php" method="GET">
<input type="text" name="search" placeholder="Search">
<button type="submit" name="submit-search"></button>
</form>
<h1> this is Auction Page </h1>
<h2>All products</h2>
<div class="product-container">
<?php
$this->db->query("SELECT * FROM article");
?>
</div>
user model code
<?php
class User{
private $db;
public function __construct(){
$this->db = new Database;
}
public function getUsers(){
$this->db->query("SELECT * FROM users");
$result = $this->db->resultSet();
return $result;
}
public function register($data){
$this->db->query('INSERT INTO users (username, email, password)
VALUES (:username, :email, :password)');
//bind values
$this->db->bind(':username', $data['username']);
$this->db->bind(':email', $data['email']);
$this->db->bind(':password', $data['password']);
//execute
if ($this->db->execute()){
return true;
}else{
return false;
}
}
public function login($username, $password){
$this->db->query('SELECT * FROM users WHERE username = :username');
//bind value
$this->db->bind(':username', $username);
$row = $this->db->single();
$hashedPassword = $row->password;
if (password_verify($password, $hashedPassword)){
return $row;
}else{
return false;
}
}
//Find user by email email is passed as argument from controller
public function findUserByEmail($email){
$this->db->query('SELECT * FROM users WHERE email = :email');
//email param binded with variabel
$this->db->bind(':email', $email);
//check if email is already registered
if ($this->db->rowCount() > 0){
return true;
}else{
return false;
}
}
}
my users controller
<?php
class Users extends Controller {
public function __construct(){
$this->userModel = $this->model('User');
}
public function register(){
$data = [
'username' => '',
'email' => '',
'password' => '',
'confirmPassword' => '',
'usernameError' => '',
'emailError' => '',
'passwordError' => '',
'confirmPasswordError' => ''
];
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
//Sanitize post data
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
$data = [
'username' => trim($_POST['username']),
'email' => trim($_POST['email']),
'password' => trim($_POST['password']),
'confirmPassword' => trim($_POST['confirmPassword']),
'usernameError' => '',
'emailError' => '',
'passwordError' => '',
'confirmPasswordError' => ''
];
$nameValidation = "/^[a-zA-Z0-9]*$/";
$passwordValidation = "/^(.{0,7}|[^a-z]*|[^\d]*)£/i";
//validate username only allow letters and numbers
if (empty($data['username'])) {
$data['usernameError'] = 'Please enter a username.';
} elseif (!preg_match($nameValidation, $data['username'])) {
$data['usernameError'] = 'Name can only contain letters and numbers.';
}
if (empty($data['email'])) {
$data['emailError'] = 'Please enter an email address.';
}elseif (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)){
$data['emailError'] = 'Please enter a VALID email address.';
}else{
//Check if email exists.
if ($this->userModel->findUserByEmail($data['email'])){
$data['emailError'] = 'Email address is registered to an existing account';
}
}
//Validate password min password and numbers
if (empty($data['password'])){
$data['passwordError'] = 'Please enter a password';
}elseif(strlen($data['password']) < 6){
$data['passwordError'] = 'Password must be greater than 6 characters';
} elseif (preg_match($passwordValidation, $data['password'])) {
$data['passwordError'] = 'Password MUST contain atleast one number.';
}
//validate confirm password matches password
if (empty($data['confirmPassword'])) {
$data['confirmPasswordError'] = 'Please confirm password';
}else{
if ($data['password'] != $data['confirmPassword']){
$data['confirmPasswordError'] = 'Passwords do not match';
}
}
//make sure that errors are empty
if (empty($data['usernameError']) && empty($data['emailError']) &&
empty($data['passwordError']) && empty($data['confirmPasswordError'])){
//hash password
$data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
//register user from model
if ($this->userModel->register($data)){
//redirect to login page after registering
header('location: ' . URLROOT . '/users/login');
}else{
die('Something went wrong');
}
}
}
$this->view('users/register', $data);
}
public function login(){
$data = [
'title' => 'Login Page',
'username' => '',
'password' => '',
'usernameError' =>'',
'passwordError' =>''
];
//check for post
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
//sanitize post data preventing people from trying to manipulate using js
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING );
$data = [
'username' => trim($_POST['username']),
'password' => trim($_POST['password']),
'usernameError' => '',
'passwordError' => '',
];
//validate username
if (empty($data['username'])){
$data['usernameError'] = 'Please enter a username';
}
//validate password
if (empty($data['password'])){
$data['passwordError'] = 'Please enter a password';
}
//check if all errors empty
if (empty($data['usernameError']) && empty($data['passwordError'])){
$loggedInUser = $this->userModel->login($data['username'], $data['password']);
if ($loggedInUser){
$this->createUserSession($loggedInUser);
}
}else{
$data['passwordError'] = 'Password or Username is incorrect. Please try again';
$this->view('users/login', $data);
}
}else{
$data = [
'username' => '',
'password' => '',
'usernameError' =>'',
'passwordError' =>''
];
}
$this->view('users/login', $data);
}
public function createUserSession($user){
$_SESSION['user_id'] = $user->id;
$_SESSION['username'] = $user->username;
$_SESSION['email'] = $user->email;
header('location:' . URLROOT . '/pages/index');
}
public function logout(){
unset($_SESSION['user_id']);
unset($_SESSION['username']);
unset($_SESSION['email']);
header('location:' . URLROOT . '/users/login');
}
public function Search(){
}
}
After register into form , data does exist in the database but when i login the data can't be fetch instead it gives a msg " Unregister Account"
Doesn't display any error but just display the msg.
if ($postjson['action'] == 'login') { //login
$password = md5($postjson['password']);
$query = mysqli_query($mysqli, "SELECT * FROM user WHERE username='$postjson[username]' AND password='$password'");
$check = mysqli_num_rows($query);
if ($check > 0) {
$data = mysqli_fetch_array($query);
$datauser = array(
'user_id' => $data['user_id'],
'username' => $data['username'],
'password' => $data['password']
);
if ($data['status'] == 'y') {
$result = json_encode(array('success' => true, 'result' => $datauser));
} else {
$result = json_encode(array('success' => false, 'msg' => 'Account Inactive'));
}
} else {
$result = json_encode(array('success' => true, 'msg' => 'Unregister Account'));
}
echo $result;
}
The database
I think your query is not getting any records because of password not matching in database.
Once your query get record it will work, Just debug why password is not matching, because of md5? give it try
In my register form I have an input which is unique but if more than two users would like to create an exact username I would like for the second username created to have a number after the typed value.
For example we have two users:
username 1: codelover
username 2: codelover2 and so on.
I currently have this in my controller:
// Create Page Data Array
$data = array(
'first_name' => strip_tags($this->input->post('first_name')),
'last_name' => strip_tags($this->input->post('last_name')),
'email' => strip_tags($this->input->post('email')),
//'username' => strip_tags($this->input->post('username')),
'ip_address' => $this->input->ip_address(),
'genre' => $this->input->post('genre'),
'slug' => $slug,
'status' => 'active',
/* 1-Founder, 2-Administrator, 3-Editor, 4-Author , 5-Contributor , 6-Subscriber , 7-Banned, 8-Suspended */
'role' => 'Subscriber',
'password' => strip_tags(password_hash($this->input->post('password'), PASSWORD_DEFAULT)),
'password2' => strip_tags(password_hash($this->input->post('password2'), PASSWORD_DEFAULT)),
);
// Is this the right approach of doing this?
$i = 0;
while($this->input->post('username') != 0){
$i++;
$data['username'] = strip_tags($this->input->post('username'.'.'.$i));
}
//Check if username and/or email already exist.
$existent_username = $this->User_model->existent_username($this->input->post('username'));
$existent_email = $this->User_model->existent_email($this->input->post('email'));
if (!empty($existent_username) || ($existent_email)) {
// Create Message
$this->session->set_flashdata('error', 'Username and/or Email already exist. Try again.');
// Redirect to pages
redirect('users/register');
} else {
// Add User
$this->User_model->add($data);
and this in my model which checks if username already exists:
public function existent_username($username) {
$query = $this->db->get_where($this->table, array('username' => $username));
return $query->row_array();
}
This is what I'm trying to do but in CodeIgniter:
if(empty($existent_username)){
$query = mysqli_query($con, "SELECT username FROM users WHERE username = '$username'");
$i = 0;
// If username already exists, add number to username
while(mysqli_num_rows($query) != 0){
$i++;
$username = $username ."." . $i;
$query = mysqli_query($con, "SELECT username FROM users WHERE username = '$username'");
}
}
First of all
// Is this the right approach of doing this?
$i = 0;
while($this->input->post('username') != 0) {
$i++;
$data['username'] = strip_tags($this->input->post('username'.'.'.$i));
}
This is wrong, its seems to me you are running an infinite loop here. I did not even understand why you need it. If you users can provide multiple username then get the input fields value first then run the loop.
Now about the main question,
you should the get all the existing usernames thats partially matches with the provided username. then generate the username and check the username already existed or not. If not then that's the username. like this.
$username = $this->input->post('username');
$existent_username = $this->User_model->existent_username($username));
if (!empty($existent_username)) {
$partially_matched_usernames = $this->db->select('username')->like('username', $username, 'after')->from('users')->get()->result_array();
$usernames_array = array_column($partially_matched_usernames, 'username');
// now generate the username
$i = 1;
while(true) {
if( ! in_array($username.$i, $usernames_array)) {
$username = $username.$i;
break;
}
$i++;
}
echo $username;
}
I did not run this code, so there could be any error. I think you will able to fix that by yourself.
how can I stay in dashboard when the user is logged even though when the user write localhost/storeLTE/login/ then stay home. but my code doesnt work.
public function getAccess(){
if ($this->session->set_userdata('username')) {
redirect('home');
}
$username = $this->security->xss_clean($this->input->post('username'));
$password = $this->security->xss_clean($this->input->post('password'));
$array = $this->User_model->login($username,$password);
if($array[0] == 0){
echo 0;
}else{
$data_session = array(
'id' => $array[0]['iduser'],
'username' => $array[0]['username'],
'password' => $array[0]['password'],
'name' => $array[0]['name'],
'last_name' => $array[0]['last_name'],
'type' => $array[0]['idType'],
'logged_in' => TRUE
);
$this->session->set_userdata('log',$data_session);
}
}
if ($this->session->set_userdata('username')) {
should be
if ($this->session->userdata('username')) {
or
if ($this->session->userdata('username') !== NULL) {
//since NULL is returned if item is not found
Docs.
FYI
Its is NOT a good sign of STORING PASSWORD IN THE SESSION. Its better to store name, type, logged_in, id.
In Controller
function getAccess(){
$this->load->library('session'); # load library here or in autoload.php
if($this->session->userdata('logged_in') == TRUE)
{
redirect('home');
}
else
{
$username = $this->security->xss_clean($this->input->post('username'));
$password = $this->security->xss_clean($this->input->post('password'));
$result = $this->User_model->login($username,$password);
if($result == FALSE)
{
echo 'Invalid Login';
}
else{
$data_session = array(
'id' => $result[0]['iduser'],
'username' => $result[0]['username'], # Better to remove
'password' => $result[0]['password'], # Better to remove
'name' => $result[0]['name'],
'last_name' => $result[0]['last_name'],
'type' => $result[0]['idType'],
'logged_in' => TRUE
);
$this->session->set_userdata('log',$data_session);
$this->load->view('home'); # Load the view
}
}
}
In Model
function login($username,$password)
{
$query = $this->db->query("SELECT * FROM table name WHERE username = '$username' AND password = '$password'");
$result = $query->result_array();
if (count($result) > 1 || empty($result))
{
return FALSE;
}
else {
return $result;
}
}
if ($this->session->set_userdata('username')) {
redirect('home');
}
change this to
if ($this->session->userdata('username') !='') {
redirect('home');
}
I have this code that is used to process user inputs from a from with the parameters email and password.
$app->post('/login', function() use ($app) {
// check for required params
verifyRequiredParams(array('email', 'password'));
// reading post params
$email = $app->request()->post('email');
$password = $app->request()->post('password');
$response = array();
$db = new DbHandler();
// check for correct email and password
if ($db->checkLogin($email, $password)) {
// get the user by email
$user = $db->getUserByEmail($email);
if ($user != NULL) {
$response["response_status"] =array('status_code'=>0, 'status_message' => 'Login Successfuly');
$response["customer_creds"] =array(array('customer_names'=>$user['name'], 'customer_email' => $user['email'], 'customer_id' => $user['customer_id'], 'customer_type' => $user['customer_type'], 'rating' => $user['rating']));
$response["customer_payment_instruments"] =array(array('payment_method'=>$user['payment_method1'], 'account_number' => $user['account_number1']),array('payment_method'=>$user['payment_method2'], 'account_number' => $user['account_number2']),array('payment_method'=>$user['payment_method3'], 'account_number' => $user['account_number3']));
$response["customer_vehicle_details"] =array(array('vehicle_plate'=>$user['vehicle_plate1'], 'vehicle_make' => $user['vehicle_make1'], 'vehicle_model' => $user['vehicle_model1'], 'vehicle_colour' => $user['vehicle_colour1'], 'vehicle_id' => $user['vehicle_id1']), array('vehicle_plate'=>$user['vehicle_plate2'], 'vehicle_make' => $user['vehicle_make2'], 'vehicle_model' => $user['vehicle_model2'], 'vehicle_colour' => $user['vehicle_colour2'], 'vehicle_id' => $user['vehicle_id2']));
} else {
// unknown error occurred
$response["response_status"] =array('status_code'=>1, 'status_message' => 'An unknown error occurred. Please try again');
//$response['error'] = true;
//$response['message'] = "An error occurred. Please try again";
}
} else {
// user credentials are wrong
$response["response_status"] =array('status_code'=>1, 'status_message' => 'Login failed. Incorrect credentials');
}
echoRespnse(200, $response);
});
This script checks if the email and password exist in the database and give a json response.
public function checkLogin ($email, $password) {
// fetching user by email
$stmt = $this->conn->prepare("SELECT password_hash FROM users WHERE email = ?");
$stmt->bind_param("s", $email);
$stmt->execute();
$stmt->bind_result ($password_hash);
$stmt->store_result();
if ($stmt->num_rows > 0) {
// Found user with the email
// Now verify the password
$stmt->fetch();
$stmt->close();
if (PassHash::check_password($password_hash, $password)) {
// User password is correct
return TRUE;
} else {
// user password is incorrect
return FALSE;
}
} else {
$stmt->close();
// user not existed with the email
return FALSE;
}
}
/**
* Fetching user by email
* #param String $email User email id
*/
public function getUserByEmail($email) {
$stmt = $this->conn->prepare("SELECT name, email, customer_id, customer_type, rating, payment_method1, account_number1, payment_method2, account_number2, payment_method3, account_number3, vehicle_plate1, vehicle_make1, vehicle_model1, vehicle_colour1, vehicle_id1, vehicle_plate2, vehicle_make2, vehicle_model2, vehicle_colour2, vehicle_id2, api_key, status, created_at FROM users WHERE email = ?");
$stmt->bind_param("s", $email);
if ($stmt->execute()) {
$user = $stmt->get_result()->fetch_assoc();
$stmt->close();
return $user;
} else {
return NULL;
}
}
I am now trying to figure out a way of allowing folks to parse json data. Any workarouds in doing this? For now script only accepts data from a form. Is there a way of allowing raw data in the format
{
"email":"",
"password":""
}
Here is the code that you can use in your current code:
Replace this code:
// reading post params
$email = $app->request()->post('email');
$password = $app->request()->post('password');
With
// reading request body
$requestBody = $app->request->getBody();
// parsing json data to php
$requestData = json_decode($requestBody, 1);
// checking if email or password is set, if not the return response
if(empty($requestData['email']) || empty($requestData['password'])) {
echoRespnse(400, ['message' => 'username/password cannot be empty']);
}
$email = $requestData['email'];
$password = $requestData['password'];
Hope this should work!!