PHP displaying error code once - php

When a user clicks login, "Wrong Email Or Password" Is displayed for each user that is in Database Array. Could someone point me in the right direction to Only Display Error code once if user input wrong email/password?
I'm Using Flintstone to store Users.
if (isset($_POST['login'])) {
$TempEmail = strtolower($_POST['email']);
$TempPass = $_POST['password'];
// Get Keys From DB;
$keys = $users->getKeys();
// Check If DB is Empty
if (!empty($keys)) {
foreach ($keys as $key) {
$user = $users->get($key);
$email = strtolower($user['Email']);
$password = $user['Password'];
$hash = password_verify($TempPass, $password);
try {
if (($TempEmail === $email) && ($hash === true))
{
$_SESSION['use']=$email;
// On Successful Login redirects to home page
header("Location:/home/");
}
else
{
echo "Wrong Email Or Password";
//break;
}
} catch (Exception $e) {
return $e->getMessage();
}
}
} else {
echo "DB Is Empty";
exit;
}
}

Simply move echo "Wrong Email Or Password" right after the foreach-loop instead of inside it. If the email is found and the password matches, the user will still be redirected before the code reaches that point.
foreach ($keys as $key) {
// Your current code, minus the echo.
}
// This is after the foreach and will only be executed if there were
// no match for the email and password.
echo "Wrong Email Or Password";
Just remember to add an exit; after your header('Location:....'); to stop PHP from executing anything more.

The foreach loop goes through all the $keys, hence it echoes "Wrong Email Or Password" for every wrong key.
Save the outcome of a successfull query in a variable i.e. $success = false. If the correct login was found, set it to true. After the foreach loop you can write
if(!$success){echo "Wrong password"};

I think this is more user-friendly:
$login = false;
foreach ($keys as $key) {
$user = $users->get($key);
$email = strtolower($user['Email']);
$password = $user['Password'];
$hash = password_verify($TempPass, $password);
try {
if ($TempEmail === $email) {
if ($hash === true) {
$login = true;
$_SESSION['use'] = $email;
// On Successful Login redirects to home page
header("Location:/home/");
} else {
break;
}
}
} catch (Exception $e) {
return $e->getMessage();
}
}
if (!$login) {
echo "Wrong Email Or Password";
}

Related

Add password hash in pdo login

I cannot manage to add a password hash in my sign up code. I am new to PDO and I tried different things but cannot manage to make a working registration with password hash!
Can someone help me? Here my code:
<?php
include('header.php');
// Check if logged in
if($user->is_loggedin()!="")
{
$user->redirect('home.php');
}
$error='';
if(isset($_POST['btn-signup']))
{
// trim empty spaces on inserted data
$uname = trim($_POST['name']);
$umail = trim($_POST['email']);
$upass = trim($_POST['password']);
$repeat_password = trim($_POST['repeat_password']);
// validate username
if($uname=="") {
$error.= "provide username ! <br>";
}
// validate e-mail
else if($umail=="") {
$error.= "provide email id ! <br>";
}
else if(!filter_var($umail, FILTER_VALIDATE_EMAIL)) {
$error.= 'Please enter a valid email address ! <br>';
}
// validate password
else if($upass=="") {
$error.= "provide password ! <br>";
}
else if(strlen($upass) < 6){
$error.= "Password must be atleast 6 characters <br>";
}
else if( $upass!=$repeat_password){
$error.= "Password Does Not Match <br>";
}
else
{
// check if email is already taken
try
{
// prepare statement
$stmt = $DB_con->prepare("SELECT email FROM users WHERE email=:umail");
$stmt->execute(array(':umail'=>$umail));
$row=$stmt->fetch(PDO::FETCH_ASSOC);
if($row['email']==$umail) {
$error.= "sorry email id already taken ! <br>";
}
// if everything is validated save data
else
{
if($user->register($uname,$umail,$upass))
{
$_SESSION['success']='You have been Registered Successfully';
$user->redirect('login.php');
}
}
}
// set the error mode
catch(PDOException $e)
{
echo $e->getMessage();
}
}
}
And here the class "user"
<?php
class User
{
private $db;
function __construct($DB_con)
{
$this->db = $DB_con;
}
// get user by passed in data
public function register($uname,$umail,$upass)
{
try
{
// $new_password = password_hash($upass, PASSWORD_DEFAULT); // Creates a password hash;
$new_password = $upass;
// prepared statement
$stmt = $this->db->prepare("INSERT INTO users(name,email,password,user_type)
VALUES(:uname, :umail, :upass,'user')");
// bind param with values
$stmt->bindparam(":uname", $uname);
$stmt->bindparam(":umail", $umail);
$stmt->bindparam(":upass", $new_password);
$stmt->execute();
return $stmt;
}
// set the error mode
catch(PDOException $e)
{
echo $e->getMessage();
}
}
public function login($umail,$upass)
{
try
{
// prepare statement
$stmt = $this->db->prepare("SELECT * FROM users WHERE email=:umail LIMIT 1");
$stmt->execute(array(':umail'=>$umail));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() > 0)
{
if($upass==$userRow['password'])
{
$_SESSION['user_id'] = $userRow['id'];
$_SESSION['name'] = $userRow['name'];
$_SESSION['role'] = $userRow['user_type'];
return true;
}
else
{
return false;
}
}
}
// set the error mode
catch(PDOException $e)
{
echo $e->getMessage();
}
}
public function is_loggedin()
{
if(isset($_SESSION['user_id']))
{
return true;
}
}
public function redirect($url)
{
header("Location: $url");
}
public function logout()
{
session_destroy();
unset($_SESSION['user_id']);
return true;
}
}
?>
In the commented line in the class script you can see a try I made, it hashed the password but then the pw wouldn't be saved in my sql database.
Sorry if the question is stupid but I am learning :)
I want to point out few things first:
Do not use trim to users password. Unless if you want to restrict your users from entering spaces to their passwords.
Use === when doing comparison. It is better because it checks datatype at the same time. For example if you have "2" and 2 and you use == operator it equals. It is good practice to check datatype because it prevents alot error from happening.
As what comes to problem that you wanted to get answer
You don't use password_hash function at any point. You only assign raw password to variable and assign this variable to bind_param function.
$new_password = $upass;
Should be instead
$new_password = password_hash($upass, PASSWORD_DEFAULT);
However i do not recommend using PASSWORD_DEFAULT as you could get more secure hash by using PASSWORD_ARGON2I. You can check more information about password_hash from PHP manual.
And to help you out even more: when you want to verify that user enters correct password at login you need to use password_verify(). It compares hash to password that user entered and if it is correct this function will return true.
Example:
$login_status = password_verify($_POST['password'], $user_password_from_database);
if($login_status === true) {//set session etc...}
You can read more about password_verify here

Why PHP authentication works incorrect?

I am newbie in PHP.
I have simple authentication script. It works incorrect: user "test" (100% existing in table in DB) can not pass auth (error text - "User is not found!").
Use PHP7, MySQL, connection method is PDO.
Need some help please.
$data = $_POST;
// check if button is pressed
if (isset($data['enter-auth'])) {
// check fileds
$errors = array();
if (trim($data['login_auth']) == '' ) {
$errors[] = 'Enter login';
}
if (($data['password_auth']) == '' ) {
$errors[] = 'Enter password';
}
// If all fields are filled, save user's data in vars
$login = $data['login_auth'];
$password = password_hash($data['password_auth'], PASSWORD_DEFAULT);
// ... and look in table
try {
if (empty($errors)) {
// Check if login and password exists in table
$stmt = $pdo->prepare("SELECT count(*) FROM users WHERE login=? AND password=?");
$stmt->execute([$login, $password]);
$count = $stmt->fetchColumn();
// If login and pwd found in table counter will be > 0, so ...
if ($count > 0) {
// ... then we can check if password is correct
if (password_verify($data['password_auth'], $password)) {
// if entered and stored passwords match, user is welcome
$_SESSION['auth_name'] = $data['login_auth'];
echo '<div style="color: green;">Welcome, '.$_SESSION['auth_name'].';
echo 'Exit';
header('Location: /a/index.php');
} else {
$errors[] = 'Password is incorrect';
echo '<p id="message">Wrong password!</p>';
}
} else {
$errors[] = 'User not found';
echo '<p id="message">User is not found!</p>';
}
} else {
echo '<div style="color: red;">'.array_shift($errors).'</div>';
}
} catch(PDOException $e) {
echo $e->getMessage();
}
// close condition check if button is pressed
}
Notes:
I tryed debugging this script using var_dump.
If I use fetchAll() when searching in table, any entered ldin is accepted (even if there is no such user).
Used try/catch construction with debug aim, I've heard that in production it is deprecated because of security reason.
Found mistakes, rewrote the code according to https://phpdelusions.net/pdo_examples/password_hash
So, correct fragment is:
try {
if (empty($errors)) {
$stmt = $pdo->prepare("SELECT login, password FROM users WHERE login=?");
$stmt->execute([$login]);
$user = $stmt->fetch();
if ($user && password_verify($data['password_auth'], $user['password'])) {
$_SESSION['auth_name'] = $data['login_auth'];
echo '<div style="color: green;">Welcome, '.$_SESSION['auth_name'].';
echo 'Exit';
header('Location: /a/index.php');
} else {
$errors[] = 'Login or password error';
echo '<p id="message-auth">Login or password is incorrect!</p>';
}
} else {
echo '<div style="color: red;">'.array_shift($errors).'</div>';
}
} catch(PDOException $e) {
echo $e->getMessage();
}

Verifying if given Username already exist in a txt file, using php

I have an assignment where i need to create a register page and verify if a user doesn't exist already in a txt file. I found some answers online and tried to apply them but doesn't seem to work for me. everything works except the part that he needs to verify.
here is my code: this is my code
<?php
if($_POST['formSubmit'] == "Submit")
{
$errorMessage ="";
$link_Create = "CreateAnAccount.php";
$Username = $_POST['userName'];
$password = $_POST['Password'];
if(empty($_POST['userName']))
{
echo "<li>You forget to enter a UserName</li><a href='".$link_Create."'>Start again</a>";
header("Location:PopUp.html");
exit;
}
if(empty($_POST['Password']))
{
echo "<li>You forget to enter a Password</li><a href='".$link_Create."'>Start again</a>";
header("Location:PopUp.html");
exit;
}
if(!preg_match('/^(?=.*\d)(?=.*[A-Za-z])[0-9A-Za-z!##$%]{4,24}$/', $password))
{
echo "<li>Your Password input was wrong, please notice Paswword most be at least 4 characters long, have at least one letter and at least one digit. </li><a href='".$link_Create."'>Start again</a>";
header("Location:PopUp.html");
exit;
}
if(empty($errorMessage)){
$userlist = fopen("login.txt","r");
$success = true;
foreach ($userlist as $user) {
$user_details = explode('|', $user);
if ($user_details[0] == $Username) {
$success = false;
break;
}
}
fclose($userlist);
if ($success==true) {
$writer = fopen("login.txt", "a") or die("Unable to open file.");
fwrite($writer,$Username."|");
fwrite($writer,$password."\n");
fclose($writer);
echo "<br>You have been logged in. <br>";
header("Location:PopUp.html");
exit;
}
else {
echo "<li>This User Name already exist!</li><a href='".$link_Create."'>Start again</a>";
header("Location:PopUp.html");
exit;
}
}
}
?>
Let me know if there is the need of my html code but i don't think it has any effect on the issue.
Thank you very much I appreciate the help.
You have problem with iterating over resource which return fopen function
$userlist = fopen("login.txt","r");
$success = true;
foreach ($userlist as $user) {
$user_details = explode('|', $user);
if ($user_details[0] == $Username) {
$success = false;
break;
}
}
Try to replace it with this iterating over each line of userlist file:
$file = new \SplFileObject("login.txt");
// Loop until we reach the end of the file
while (!$file->eof()) {
$user = $file->fgets();
$user_details = explode('|', $user);
if ($user_details[0] == $Username) {
$success = false;
break;
}
}

Trying to get login error messages/validation to work on login form?

I have a login system for a member/admin site. The login is working perfectly, but I want to verify the user and give error messages if it's not the correct user or password. So far, with what I have, it will not give any error messages although I'm not getting any errors either.
function error_message(){ $error = '';
$loginName = isset($_REQUEST['loginName']) ? $_REQUEST['loginName'] : "";
$password = isset($_REQUEST['password']) ? $_REQUEST['password'] : "";
{$results = connect($loginName);
$loginName === $results['email'];
$passwords = password_verify($password,$results['password']);
if(!$results) {$error = 'Username not found'; echo $error; header ('Location: home.php');} //if no records returned, set error to no username
else //if found {if ((isset($password)) !== (isset($passwords))) //check password, if matched log him in
{ $error = 'Password is wrong'; echo $error; header('Location: home.php');} //if not matched then set error message
}
}
if(isset($error)) {echo $error; }//if there is an error print it, this can be anywhere in the page
}
This is my connection and how it is logging in:
function connect($loginName) {
global $db;
$query = "SELECT email, level, password FROM members WHERE email ='$loginName'";
$result = $db->query($query);
$results = $result->fetch(PDO::FETCH_ASSOC);
return $results;
}
Login:
function login($loginName, $password) {
$results = connect($loginName);
if(!$results) {
header('Location: /tire/admin/home.php?err=1');
}
if ($loginName === $results['email'] && password_verify($password,$results['password'])) {
$_SESSION['loginName'] = $loginName;
if ($results['level'] === 'a') { // 1 == Administrator
$_SESSION['level'] = 'Administrator';
header('Location: /tire/admin/home.php');
} elseif ($results['level'] === 'm') { // 1 == Member
$_SESSION['level'] = 'Member';
header('Location: /tire/member/home.php');
exit;
}
}
header('Location: /tire/admin/home.php');
}
Wow, that's some nasty code we have here. Let's get started:
Let's first take a look in the connect function:
Gets the row where the email matches the loginName provided.
Return the array with the desired row.
That's correct.
Now let's take a look to the login function:
Retrieves the row where the email matches loginName.
If there is no row (email does not match any user), redirects to home.php of ¿ADMIN? with the variable $err = 1.
Recheck the email (what for?) and verify the password.
If password is correct, it checks permissions and redirects to the correspondent home.php.
Notice that if there is no matches for a permission, it redirects you to admin home.php.
Notice that if the password is incorrect, you do nothing.
I will improve this code:
function login($loginName, $password) {
$results = connect($loginName);
if(!$results) {
header('Location: /tire/error.php?code=1');
}
if (password_verify($password,$results['password'])) {
$_SESSION['loginName'] = $loginName;
if ($results['level'] === 'a') { // 1 == Administrator
$_SESSION['level'] = 'Administrator';
header('Location: /tire/admin/home.php');
} elseif ($results['level'] === 'm') { // 1 == Member
$_SESSION['level'] = 'Member';
header('Location: /tire/member/home.php');
exit;
}
} else {
header('Location: /tire/error.php?code=2');
}
}
And then in error.php (or whatever place you would like to show the errors, it's just an example):
switch($_GET['code']){
case 1:
$error = "Email invalid";
break;
case 2:
$error = "Password invalid";
break;
}
print $error
That being said, I will strongly recommend you to read about exceptions and implement the logic based on that. It's far more clean than the code above, but I didn't want to change your code so drastically.
See: http://php.net/manual/en/language.exceptions.php

How to choose page using if else in mysql_num_rows

Please help me I want my program to choose a site if it has not yet username then it will proceed it to ch_uname.php. Then if the login credentials have already username then it will be preceded to index_profile.php. Thank you in advance.
if(mysql_num_rows($runcreds)> 0 ) //checking log in forms
{
if(mysql_num_rows($run_uname)>=1 ) //if username has already avalaible(proceed)
{
$_SESSION['Email_add']=$email;
echo "<script>window.open('modules/index_profile.php','_self')</script>";
}
if(mysql_num_rows($run_uname)<1)//choouse username if has not yet username
{
$_SESSION['Email_add']=$email;
echo "<script>window.open('forms/ch_uname.php','_self')</script>";
//modules/index_profile.php
}
}
else
{
echo "<script>alert('Admin details are incorrect!')</script>";
}
}
Here is a basic demonstration (using a PDO connection) of what I think you are looking for? I am assuming some stuff here because you don't give enough info before your code snippet:
session_start();
// I will use PDO because I cannot bring myself to use mysql_ in this demonstration
// Initiate connection (assigning credentials assumed)
$con = new PDO("mysql:host=$mysqlDB;dbname=$mysqlTable", $mysqlUser, $mysqlPass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT));
if(isset($_POST['login'])) {
$username = trim($_POST['username']);
// Stop if empty
if(empty($username)) {
// You can echo or assign to a variable to echo down the page
echo 'Username cannot be empty';
return;
}
// Set up prepared statement
$query = $con->prepare("select Email_add,password from `users` where username = :username");
$query->execute(array(":username"=>$username));
// Loop through returned
while($row = $query->fetch(PDO::FETCH_ASSOC)) {
$result[] = $row;
}
// If the loop comes up blank, assign false (0)
$result = (isset($result) && !empty($result))? $result:0;
// If username exists
if($result != 0) {
// I am assuming you have some form of super secure hash method for passwords...
$password = bcrypt($_POST['password']);
// If passwords match, create session
if($result[0]['password'] == $password) {
$_SESSION['Email_add'] = $result[0]['Email_add'];
// You probably don't need javascript to redirect
header('Location: modules/index_profile.php');
exit;
}
else {
// Password doesn't match
// You can echo or assign to a variable to echo down the page
echo 'Invalid Username/Password';
}
}
// This would mean the username doesn't exist
else {
header('Location: forms/ch_uname.php');
exit;
}
}

Categories