I am working on a login form and the password doesn't get verified from some reason. The user supposed to log in into system with email and password. I am matching user based on the email with the data in database. Could you please look at it?
Customer table
HTML form in file index.php
<div id="test-popup" class="white-popup mfp-hide col-sm-4 col-sm-offset-4 col-xs-10 col-xs-offset-1 align-center">
<img src="images/logo-white.png" alt="" height="120px" width="120px" />
<h5 class="font-alt">Login to Your Account</h5>
<br/>
<form method="post" action="login.php" class="form">
<div class="mb-20 mb-md-10">
<input type="text" name="email" id="email" class="input-md form-control" placeholder="Email" required />
</div>
<div class="mb-20 mb-md-10">
<input type="password" name="password" id="password" class="input-md form-control" placeholder="Password" required />
</div>
<div class="mb-20 mb-md-10">
<input type="submit" name="login" class="login btn btn-mod btn-medium" id="btnLogIn" value="Login" />
</div>
</form>
</div>
File login.php
<?php
require_once 'connection_db.php';
$response = new stdClass;
if (empty($_POST['email']) || empty($_POST['password'])) {
$response->success = false;
$response->message = 'Email and password cannot be empty.';
} else {
$sql = 'SELECT * FROM `customer` WHERE `email` = ? ';
$email = $_POST['email'];
$password = $_POST['password'];
$password = password_hash($password, PASSWORD_DEFAULT);
// print_r($password, true);
try {
$stmt = $db->prepare($sql);
$stmt->bind_param('s', $email);
$stmt->execute();
$result = $stmt->get_result();
$array = $result->fetch_array(MYSQLI_ASSOC);
// print_r($array, true);
if (count($array)) {
$response->success = true;
$response->message = 'Login successful.';
session_start();
$_SESSION['email'] = $email;
$_SESSION['id'] = $id;
$_SESSION['current_page'] = $_SERVER['HTTP_REFERER'];
header("Location: ". $_SESSION['current_page']);
} else {
$response->success = false;
$response->message = 'Wrong username or password.';
header("Location: index.php#test-popup");
}
}
catch (Exception $e) {
$response->success = false;
$response->message = "Error.";
}
}
// unset($db);
?>
Here's a generic setup of how your login script should look:
if (isset($_POST['submit']))
{
$email = $_POST['email'];
$password = $_POST['password'];
if (!empty($email) && !empty($password))
{
$res = $dbh->prepare("SELECT * FROM `customer` WHERE `email` = ?");
$res->execute([$email]);
$row = $res->fetch(MYSQLI_ASSOC);
if ($res->rowCount() > 0)
{
if (password_verify($password, $row['password']))
{
$_SESSION['user_session'] = $row['uid'];
header('Location: loggedIn.php');
} else {
// echo incorrect pass
}
} else {
// echo no such user...
}
} else {
// echo something...
}
}
You should be using password_verify for your login script. You only use password_hash for registering to hash the password that has been submitted.
<?php
if(isset($_POST["submit"])){
require 'Config.php';
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
$Name = $_POST['Name'];
$Password = $_POST['Password'];
$message ="";
$stmt = $conn->prepare("SELECT COUNT(*) FROM user WHERE Name='$Name' and Password='$Password'");
$stmt->execute();
$result = $stmt->fetchcolumn();
if($result > 0)
{
$_SESSION['Logged In'] = $Name;
$_SESSION['Logged In'] = $Password;
if(isset($_SESSION['Logged In']))
{
echo $result;
session_start();
header('Location: Main.php');
exit();
}
}
elseif($result == 0)
{
echo $result;
echo "Invalid Username or Password";
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
$conn = null;
}
?>
i need help with this simple login system if i comment out the header redirect the echo result shows i am only getting 1 result as expected when i put the redirect in the page just refreshes instead of going to the next page.
There are a few simple issues in this code
First you must start the session before you do anything with it. In fact its best to start it at the top of every script before doing anything else.
Also because you have echoed something to the browser before you have run the header, this will be a probelm. Headers have to be sent before any page data.
Also your code is liable to SQL Injection so use prepared and parameterised queries to avoid this.
You also appear to be storing a plain text password in the database. another big No No
PHP provides password_hash()
and password_verify() please use them.
And here are some good ideas about passwords
If you are using a PHP version prior to 5.5 there is a compatibility pack available here
<?php
session_start();
if(isset($_POST["submit"])){
require 'Config.php';
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
$stmt = $conn->prepare("SELECT Password
FROM user
WHERE Name=:name");
$params = array(':name'=>$_POST['Name'])
$stmt->execute($params);
$hashedPassword = $stmt->fetchcolumn();
if(password_verify($_POST['Password'], $hashedPassword) ) {
$_SESSION['Logged In'] = $_POST['Name'];
// bad idea putting password in a session
//$_SESSION['Logged In'] = $Password;
// you just set this data so the if is unnecessary
//if(isset($_SESSION['Logged In'])) {
// cannot echo anything before doing a header()
// any way if the header works you wont see this data
// anyway as a new page will be being loaded
//echo $result;
header('Location: Main.php');
exit;
} else {
echo $result;
echo "Invalid Username or Password";
}
catch(PDOException $e) {
echo $e->getMessage();
}
$conn = null;
}
?>
As this now uses a hashed password, you will have to recreate your users and when tou do, use
$passwordToPutOnDatabase = password_hash($thepassword);
There are may issues with your code, you are storing passwords in plain text which is completely wrong, you should use password_hash() and password_verify()
I have made you a simple login/register script which will show you how to use the password_hash and password_verify()
simple_register.php
<?php
require 'db_config.php';
if(isset($_POST['register'])){
//validate email and password I'm not gonna do that for you
$password = $_POST['upass']; // when u done with validation
$email = $_POST['username'];
$hash = password_hash($password,PASSWORD_DEFAULT); //hash password
try {
$stmt = $conn->prepare("INSERT INTO users (username,password) VALUES ( ?,?)");
if($stmt->execute(array($email,$hash))){
echo "user registered";
}else{
echo "could not register"; // something wrong with your query check error log
}
} catch (Exception $e) {
error_log($e->getMessage());
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Simple PDO Registration</title>
</head>
<body>
<form method="POST" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
<p><input type="email" name="username" placeholder="Enter your email"></p>
<p><input type="password" name="upass" placeholder="Enter password"></p>
<button type="submit" name="register">Register</button>
</form>
</body>
</html>
login.php
<?php
ob_start();
session_start();
require 'db_config.php';
if (isset($_SESSION['loggedin'])) {
header("location:users/dashboard.php");
} else {
$loginMessage = "";
$msg_class = "";
if (isset($_POST['login'])) {
if (empty($_POST['email']) || empty($_POST['upass'])) {
$loginMessage = "Enter username and password";
$msg_class = "error";
} else {
$username = $_POST['email'];
$password = $_POST['upass'];
try {
$stmt = $conn->prepare("SELECT userID,username,password FROM users where username = ? ");
$stmt->execute([$username]);
$results = $stmt->fetchall(PDO::FETCH_ASSOC);
if (count($results) > 0) {
foreach ($results as $row):
if (password_verify($password, $row['UserPassword'])) {
$_SESSION['loggedin'] = $row['userID'];
$loginMessage = "Login Successfully! Redirecting...";
$msg_class = "success";
header("refresh:5; url=dashboard");
} else {
$loginMessage = "Password and username does not match";
$msg_class = "error";
}
endforeach;
} else {
$loginMessage = "Invalid username";
}
}
catch (PDOException $e) {
error_log($e);
}
}
}
}
?>
</head>
<body>
<div id="main">
<h1>User Login</h1>
<div class="row">
<div class="large-6 columns large-centered" id="box">
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post">
<label>Email</label>
<input type="text" name="email" class="input" >
<label>Password </label>
<input type="password" name="upass" class="input" id="password"/><br/>
<div class="large-6 columns pull-2">Forgot Password</div>
<button type="submit" class="button" name="login" disabled="true" id="long">Login</button>
<div class="<?php echo $msg_class;?>">
<?php
echo $loginMessage;
?>
</div>
</form>
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){
$('#password').keyup(function(e){
$('#long').prop('disabled', false);
});
});
</script>
</div>
db_config.php
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "samedicalspecialists";
try {
$conn= new PDO("mysql:host=$servername;dbname=$dbname",$username,$password);
$conn->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
error_log($e);
}
?>
I have login/register form which are working perfectly. Now I'm trying to make script to allow user to change password but I can't understand why doesn't work. This is the HTML form
<form action="editAccount.php" method="post">
<div class="input-group">
<span class="input-group-addon">Password:</span>
<input type="password" name="password" class="form-control" placeholder="password">
</div>
<button class="btn btn-primary custom-button btn-block" type="submit"><i class="fa fa-check"></i> Save Changes</button>
<div class="input-group">
<span class="input-group-addon">Confirm password:</span>
<input type="password" name="passwordConfirm" class="form-control" placeholder="Confirm password">
</div>
</form>
And this is the PHP part
if(empty($_SESSION['id']))
{
header("Location: userAction.php");
die("Redirecting to userAction.php");
}
if(isset($_POST['submit']))
{
//basic validation
if(strlen($_POST['password']) < 3){
$error[] = 'Password is too short.';
}
if(strlen($_POST['passwordConfirm']) < 3){
$error[] = 'Confirm Password is too short.';
}
if($_POST['password'] != $_POST['passwordConfirm']){
$error[] = 'Password and Confirm password doesn't match.';
}
if(empty($error)){
$hashedpassword = $user->password_hash($_POST['password'], PASSWORD_BCRYPT);
try {
$stmt = $pdo->prepare("UPDATE users SET password = :hashedpassword WHERE id = :user_id");
$stmt->execute(array(
':hashedpassword' => $hashedpassword,
':user_id' => $_SESSION['id']
));
header('Location: userAction.php?action=joined');
exit;
} catch(PDOException $e)
{
$error[] = $e->getMessage();
}
}
}
On var_dump($_POST['password'] result is - string(11) "newpassword" i.e. POST got the password.
On var_dump($hashedpassword) result is - NULL. So the problem must be in hashing function.
Here is also what I have in $user
class User extends Password{
private $_db;
function __construct($pdo){
parent::__construct();
$this->_db = $pdo;
}
private function get_user_hash($username){
try {
$stmt = $this->_db->prepare('SELECT password FROM users WHERE username = :username AND active="Yes" ');
$stmt->execute(array('username' => $username));
$row = $stmt->fetch();
return $row['password'];
} catch(PDOException $e) {
echo '<p class="bg-danger">'.$e->getMessage().'</p>';
}
}
public function login($username,$password){
$hashed = $this->get_user_hash($username);
if($this->password_verify($password,$hashed) == 1){
$_SESSION['loggedin'] = true;
return true;
}
}
public function login_user_id($username){
try {
$stmt = $this->_db->prepare('SELECT id FROM users WHERE username = :username');
$stmt->execute(array('username' => $username));
$row = $stmt->fetch();
return $row['id'];
} catch(PDOException $e) {
echo '<p class="bg-danger">'.$e->getMessage().'</p>';
}
}
public function logout(){
session_destroy();
}
public function is_logged_in(){
if(isset($_SESSION['loggedin']) && $_SESSION['loggedin'] == true){
return true;
}
}
}
As you told in comments, it doesn't even enter into the if(isset($_POST['submit'])) { part, because you don't have an input named "submit".
Try it with an <input type="submit" name="submit"> or a hidden input named "submit".
I have been trying to figure this out for over two days, I am following a youtube tutorial, with a basic sign in for my Android Application, but before I do that I want to test the .php script.
I am thinking that I should get a success when I press the login button but I am getting Invalid credentials, and I know that the username and password is correct
Below is my login.php script.
require("config.inc.php");
if (!empty($_POST)) {
//gets user's info based off of a username.
$query = "SELECT id, username, passwrd
FROM application_users
WHERE
username = :username
";
$query_params = array(
':username' => $_POST['username']
);
try {
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch (PDOException $ex) {
// For testing, you could use a die and message.
//die("Failed to run query: " . $ex->getMessage());
//or just use this use this one to product JSON data:
$response["success"] = 0;
$response["message"] = "Database Error1. Please Try Again!";
die(json_encode($response));
}
//This will be the variable to determine whether or not the user's information is correct.
//we initialize it as false.
$validated_info = false;
//fetching all the rows from the query
$row = $stmt->fetch();
echo $row;
if ($row) {
//if we encrypted the password, we would unencrypt it here, but in our case we just
//compare the two passwords
if ($_POST['password'] === $row['password']) {
$login_ok = true;
}
}
// If the user logged in successfully, then we send them to the private members-only page
// Otherwise, we display a login failed message and show the login form again
if ($login_ok) {
$response["success"] = 1;
$response["message"] = "Login successful!";
die(json_encode($response));
} else {
$response["success"] = 0;
$response["message"] = "Invalid Credentials!";
die(json_encode($response));
}
} else {
?>
<h1>Login</h1>
<form action="login.php" method="post">
Username:<br />
<input type="text" name="username" placeholder="username" />
<br /><br />
Password:<br />
<input type="password" name="password" placeholder="password" value="" />
<br /><br />
<input type="submit" value="Login" />
</form>
Register
</form>
<?php
}
?>
So when the script loads and I input the values from the remote MYSQL server, the message comes back as invalid credentials.I just want to make sure my login is successful before I head over to the android part, which would be a big todo in itself.
I haven't had the opportunity to test it with a real database, but this should work. You still have to add the require("config.inc.php"); on the top of the file and I've added a custom database connection. I also work with PDO so the queries may look like different than what you've used so far.
<?php
// Database connection
try
{
$db = new PDO('mysql:host=localhost;dbname=mydatabase', 'myusername', 'mypassword');
$db->exec('SET CHARACTER SET UTF8');
}
catch (Exception $e)
{
//Message in case of error when connecting to the database
die('Erreur : ' . $e->getMessage());
}
// *** End database connection
$username = ""; // Initialize value in order to keep its value so the user can still see it in his form
if (isset($_POST['login'])) { // if the "login" button is pressed
$username = $_POST['username']; // retrieve username value from the form
$password = $_POST['password']; // retrieve password value from the form
/*
* If a username is unique then a way to do it is to count how many times
* the couple with this username and this password appears in our database.
*/
$query = $db->prepare("SELECT COUNT(*) userAmount ".
"FROM application_users ".
"WHERE username = $username ".
"AND password = $password;");
$query->execute();
$query->closeCursor();
$resultAmount = $query->fetch();
if ($resultAmount['userAmount'] == 0){ // If the couple username-password is unfound
$message = "Username or password unknown";
} else {
$message("Login successful");
}
}
?>
<h1>Login</h1>
<form action="login.php" method="post">
Username:<br />
<input type="text" name="username" placeholder="username" value="<?php echo($username); ?>" />
<br/><br/>
Password:<br/>
<input type="password" name="password" placeholder="password" value="" />
<br/><br/>
<input type="submit" name="login" value="Login" />
Register
</form>
So I have two files, one is index.php and register.php. Index is the form and register is the PHP handling the form. So here's index.php
<!DOCTYPE html>
<html lang="en">
<body>
<div class="container">
<form class="form-signin" role="form" action="register.php" method="post">
<h2 class="form-signin-heading">Please sign up</h2>
<input type="text" class="form-control" placeholder="Name" name="name" autofocus style="border-color:#<?php ?>;">
<input type="text" class="form-control" placeholder="Username" name="username" autofocus>
<input type="text" class="form-control" placeholder="Email" name="email" autofocus>
<input type="password" class="form-control" placeholder="Password" name="password">
<input type="password" class="form-control" placeholder="Password, Again" name="passwordconf" >
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign up</button>
</form>
</div>
</body>
</html>
And my register.php
<?php
try {
$handler = new PDO('mysql:host=localhost;dbname=s','root', '*');
$handler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e){
exit($e->getMessage());
}
//Post
$name = $_POST['name'];
$username = $_POST['username'];
$email = $_POST['email'];
$password = $_POST['password'];
$password1 = $_POST['passwordconf'];
$ip = $_SERVER['REMOTE_ADDR'];
//Verifcation
if (empty($name) || empty($username) || empty($email) || empty($password) || empty($password1))
{
echo "Complete all fields";
}
// Password match
if ($password != $password1)
{
echo $passmatch = "Passwords don't match";
}
// Email validation
if (!filter_var($email, FILTER_VALIDATE_EMAIL))
{
echo $emailvalid = "Enter a valid email";
}
// Password length
if (strlen($password) <= 6){
echo $passlength = "Choose a password longer then 6 character";
}
if(empty($passmatch) && empty($emailvalid) && empty($passlength)) {
//Securly insert into database
$sql = 'INSERT INTO userinfo (name ,username, email, password, ip) VALUES (:name,:username,:email,:password,:ip)';
$query = $handler->prepare($sql);
$query->execute(array(
':name' => $name,
':username' => $username,
':email' => $email,
':password' => $password,
':ip' => $ip
));
}
?>
But here's what I want to do, I want to display the PHP errors alongside the form instead of having them displayed on register.php But I also want to use two separate files. Instead of combining the two files together. Any ideas?
I seriously don't understand your use of server side to do all these validations. It is wise and economical to do this in the client side itself. There are a hell lot of plugins for client side form validation, if that's the case for you.
A few scripts would be:
jQuery Form Validator
jQuery Validation Plugin
jQuery plugin: Validation
10 jQuery Form Validation Techniques and Tutorials
Find the last link to do the work yourself.
In your case, please try to separate the view and logic. It is also wise to follow Model-View-Controller architecture that is followed in many of the PHP Web Applications and JavaScript Apps now-a-days.
Or if you somehow need the logic to be done in server side, separate the form by putting the HTML inside form.php. And in your validation, do a small change, by including a flag, which is set to false, when the form is not validated.
Now, if the validation is not successful, i.e., the flag $valid = false, then you include the form.inc, else include success.inc.
if ($valid)
include 'success.inc';
else
include 'form.inc';
And since it is going to be in the same file, in the form.inc, add this line:
if (!$valid)
echo '<p class="error">You have errors in your form! Please correct them!</p>';
At the bottom of register.php simply call:
include 'index.php';
And your form will be displayed.
Add a line to display errors in your index.php:
<?php if (!empty($error)) { ?>
<?php echo "error occured: ".$error; ?>
<?php } ?>
This is a style of MVC programming (Model-View-Controller). The idea is not to echo things all over the place within register.php, instead you build up an application state in a model and then the view (index.php) reads from the model.
Try this out:
<!DOCTYPE html>
<html lang="en">
<body>
<div class="container">
<?php
if(isset($_POST['submit'])){
try {
$handler = new PDO('mysql:host=localhost;dbname=s','root', '*');
$handler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e){
exit($e->getMessage());
}
//Post
$name = $_POST['name'];
$username = $_POST['username'];
$email = $_POST['email'];
$password = $_POST['password'];
$password1 = $_POST['passwordconf'];
$ip = $_SERVER['REMOTE_ADDR'];
//Verifcation
if (empty($name) || empty($username) || empty($email) || empty($password) || empty($password1))
{
echo "Complete all fields";
} if ($password != $password1)
{
echo $passmatch = "Passwords don't match";
} else if (!filter_var($email, FILTER_VALIDATE_EMAIL))
{
echo $emailvalid = "Enter a valid email";
} else if (strlen($password) <= 6){
echo $passlength = "Choose a password longer then 6 character";
} if(empty($passmatch) && empty($emailvalid) && empty($passlength)) { // You don't need this line, you already checked above if these POST variables were empty.
//Securly insert into database
$sql = 'INSERT INTO userinfo (name ,username, email, password, ip) VALUES (:name,:username,:email,:password,:ip)';
$query = $handler->prepare($sql);
$query->execute(array(
':name' => $name,
':username' => $username,
':email' => $email,
':password' => $password,
':ip' => $ip
));
}
}
?>
<form class="form-signin" role="form" action="" method="post">
<h2 class="form-signin-heading">Please sign up</h2>
<input type="text" class="form-control" placeholder="Name" name="name" autofocus style="border-color:#<?php ?>;">
<input type="text" class="form-control" placeholder="Username" name="username" autofocus>
<input type="text" class="form-control" placeholder="Email" name="email" autofocus>
<input type="password" class="form-control" placeholder="Password" name="password">
<input type="password" class="form-control" placeholder="Password, Again" name="passwordconf" >
<button class="btn btn-lg btn-primary btn-block" name='submit' type="submit">Sign up</button>
</form>
</div>
</body>
</html>
Few notes:
Leaving the action value blank will cause the form to post back to
itself.
I will fix the spacing when I get home, I don't have my editor with me.
The errors should be displayed underneath the container. I made it so that only one error is display at a time, do let me know if you
want to display all the errors at once.
I wouldn't recommend doing the registration form this way, it's way too messy. However, if this is your learning process, then all the power to you.
register.php
<?php
//Connections
try {
$handler = new PDO('mysql:host=localhost;dbname=s','root', '*');
$handler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e){
exit($e->getMessage());
}
//Post shit
$name = $_POST['name'];
$username = $_POST['username'];
$email = $_POST['email'];
$password = $_POST['password'];
$password1 = $_POST['passwordconf'];
$ip = $_SERVER['REMOTE_ADDR'];
$error = null;//set it to null
//Verifcation
if (empty($name) || empty($username) || empty($email) || empty($password) || empty($password1)){
$error .= "Complete all fields\n";
}
// Password match
if ($password != $password1){
$error .= "Passwords don't match\n";
}
// Email validation
if (!filter_var($email, FILTER_VALIDATE_EMAIL)){
$error .= "Enter a valid email\n";
}
// Password length
if (strlen($password) <= 6){
$error .= "Choose a password longer then 6 character\n";
}
if(!isset($error)){
//no error
$sthandler = $handler->prepare("SELECT username FROM users WHERE username = :name");
$sthandler->bindParam(':name', $username);
$sthandler->execute();
if($sthandler->rowCount() > 0){
error .= "exists! cannot insert\n";
} else {
//Securly insert into database
$sql = 'INSERT INTO userinfo (name ,username, email, password, ip) VALUES (:name,:username,:email,:password,:ip)';
$query = $handler->prepare($sql);
$query->execute(array(
':name' => $name,
':username' => $username,
':email' => $email,
':password' => $password,
':ip' => $ip
));
}
}else{
error .= "error occured: ".$error;
}
if(!isset($error)){
header( 'Location: index.php' ) ;
}
else {
header( 'Location: register.php?err='.$error ) ;
}
To display the error on your form place this code:
if(isset($_GET['err'])){
$error = $_GET['err'];
echo "error: $error";
}