How to use bcrypt for user data with PHP/MySQL/JSON - php

I'm currently developing an android application and using PHP/MySQL/JSON for the user registration and the login procedere. Now i want to use bcyrpt for hashing the user data. I am totally new to PHP and read a lot of tutorials for hashing, but i do not found any proper tutorial for my PHP skript which i can use.
I tried the password_hash() function, but it won't work.
Can you please give me advice how i can use bcrypt with my files.
Those are my PHP files:
LOGIN
<?php
require("config.inc.php");
if (!empty($_POST)) {
$query = "
SELECT
id,
username,
password
FROM users
WHERE
username = :username
";
$query_params = array(
':username' => $_POST['username']
);
try {
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch (PDOException $ex) {
$response["success"] = 0;
$response["message"] = "Database Error1. Please Try Again!";
die(json_encode($response));
}
$validated_info = false;
$row = $stmt->fetch();
if ($row) {
if ($_POST['password'] === $row['password']) {
$login_ok = true;
}
}
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
<?php
}
?>
REGISTER
<?php
require("config.inc.php");
if (!empty($_POST)) {
if (empty($_POST['username']) || empty($_POST['password'])) {
$response["success"] = 0;
$response["message"] = "Please Enter Both a Username and Password.";
die(json_encode($response));
}
$query = " SELECT 1 FROM users WHERE username = :user";
$query_params = array(
':user' => $_POST['username']
);
try {
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch (PDOException $ex) {
$response["success"] = 0;
$response["message"] = "Database Error1. Please Try Again!";
die(json_encode($response));
}
$row = $stmt->fetch();
if ($row) {
$response["success"] = 0;
$response["message"] = "I'm sorry, this username is already in use";
die(json_encode($response));
}
$query = "INSERT INTO users ( username, password ) VALUES ( :user, :pass ) ";
$query_params = array(
':user' => $_POST['username'],
':pass' => $_POST['password']
);
try {
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch (PDOException $ex) {
$response["success"] = 0;
$response["message"] = "Database Error2. Please Try Again!";
die(json_encode($response));
}
$response["success"] = 1;
$response["message"] = "Username Successfully Added!";
echo json_encode($response);
} else {
?>
<h1>Register</h1>
<form action="register.php" method="post">
Username:<br />
<input type="text" name="username" value="" />
<br /><br />
Password:<br />
<input type="password" name="password" value="" />
<br /><br />
<input type="submit" value="Register New User" />
</form>
<?php
}
?>

In your register script you should not store the password directly, instead call the password_hash() function and store its result:
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($_POST['password'], PASSWORD_DEFAULT);
In the login script you can get the password-hash from the database as you did, but instead of comparing it with the entered password, you have to call the password_verify() function:
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($_POST['password'], $existingHashFromDb);

Related

Login form doesn't verify the password

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.

how to implement token base form submission in php

i have been trying to create my own OOPs style register login system in php, i have implemented some security features like xss protection using htmlentites(), prepare method for SQLinjection protection and token based form submission for csrf protection(currently i am stuck implementing this functions in my code, getting "Invalid token" while submitting form data).
But I am not very sure it is good enough for secure site to produce for real live project or not. And i would like you to review my codes, Please help me to solve implementing token base form submission in my code and suggest me the way to improve my coding style in my current code.
This is my register.php page
<?php
//error_reporting(0);
session_start();
if(isset($_POST["submit"])){
include "Db_handlers.php";
$db = new DbHandler();
$res = $db->createUser($_POST["name"], $_POST["email"], $_POST["password"], $_POST["re-password"], $_POST['token']);
print_r($res);
/*if($res){
echo "test";
}
else {
echo $res;
}*/
}
$token = $_SESSION['token'] = md5(uniqid(mt_rand(),true));
?>
<form action="<?=$_SERVER['PHP_SELF'];?>" method="post">
<div class="field">
<label for="name">Name:</label>
<input type="text" name="name" value="" />
</div>
<div class="field">
<label for="email">Email:</label>
<input type="text" name="email" value="" />
</div>
<div class="field">
<label for="password">Password:</label>
<input type="password" name="password" value="" />
</div>
<div class="field">
<label for="repassword">Re-Password:</label>
<input type="password" name="re-password" value="" />
</div>
<input type="hidden" name="token" value="<?=$token;?>"/>
<input type="submit" name="submit" value="submit" />
</form>
This is my DB handler class
<?php
require 'functions.php';
class DbHandler {
private $conn;
public function __construct() {
try{
$this->conn = new PDO("mysql:host=127.0.0.1;dbname=task_manager", "root" , "");
// echo "Connected";
}
catch(PDOException $e){
//die($e->getMessage());
echo "Connection Failed: ".$e->getMessage();
}
}
public function createUser($name, $email, $password, $repassword, $utoken) {
// $error = array();
$error = '';
$required_fields = array($name, $email, $password, $repassword);
$fields = array_map('trim', $required_fields);
if (in_array(null, $fields)) {
$error = 'Fields marked with an asterisk are required';
}
else if($this->valid_token($utoken) == false){
$error = "Invalid Token...!!!";
}
else if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = 'Please enter a valid email address !';
}
else if(strlen($password) < 6){
$error = "Password must be atleast 6 characters";
}
else if($password !== $repassword){
$error = "Password do n\' t match!!";
}
else{
$name = escape($name);
$email = escape($email);
$password_hash = escape($password);
// First check if user already existed in db
if (!$this->isUserExists($email)) {
// Generating password hash
$password_hash = password_hash($password, PASSWORD_DEFAULT, ['cost'=>12]);
// insert query
$stmt = $this->conn->prepare("INSERT INTO users(name, email, password_hash, status) values(:name, :email, :password_hash, 1)");
//$stmt->bind_param("ssss", $name, $email, $password_hash);
$result = $stmt->execute(array(':name' => $name,':email' => $email,':password_hash' => $password_hash));;
//$stmt->close();
// Check for successful insertion
if ($result) {
// User successfully inserted
return $result;
} else {
// Failed to create user
$error = "Failed to create user";
}
} else {
// User with same email already existed in the db
$error = "User already exists";
}
}
return $error;
}
private function isUserExists($email) {
$stmt = $this->conn->prepare("SELECT id from users WHERE email = :email");
//$stmt->bind_param("s", $email);
$stmt->execute(array(':email' => $email));
//$stmt->bind_result();
$num_rows = $stmt->rowCount();
//$stmt->close();
return $num_rows > 0;
}
public function valid_token($token){
if(!isset($_SESSION['token']) || $token != $_SESSION['token'])
return false;
}
}
Your code is really hard to read... You should indent it properly.
Back to your question. It seems, you just return false, if your token is incorrect, but your forget to return true, if it is correct. If your return nothing, you implicitly return null, which evaluates to false. I guess, your code works, if your change valid_token like this:
public function valid_token($token){
return isset($_SESSION['token']) && $token == $_SESSION['token'];
}

PHP login form not working with mysql

<?php
if(array_key_exists("logIn",$_POST))
{
$link = mysqli_connect("dbaddress", "dbname", "dbpassword", "dbuser");
if(!$_POST['regno'])
{
$error .= "Please enter your registration number";
}
if(!$_POST['password'])
{
$error .= "Password is required!";
}
if($error!="")
{
echo "<p>There were errors in your forms!</p>".$error;
}
else
{
$query = "SELECT * FROM `users` WHERE RegistrationNo = '".mysqli_real_escape_string($link, $_POST['regno'])."'";
$result = mysqli_query($link, $query);
$row = mysqli_fetch_array($result);
if (isset($row)) {
$hashedPassword = md5(md5($row['id']).$_POST['password']);
if ($hashedPassword == $row['password']) {
$_SESSION['id'] = $row['id'];
header("Location: after_login.php");
}
else {
$error = "That email/password combination could not be found.";
}
}
else {
$error = "That email/password combination could not be found.";
}
}}
?>
<form method="post">
<center><input type="text" placeholder="Enter Username" name="regno" id="log_username" class="sidelog"/>
<input type="password" placeholder="Enter Password" name="password" id="real_pass" class="sidelog"/>
</br><button id="button_log" type="submit" name="logIn" > GO </button> </center>
</form>
The page reloads whenever I fill the form and submit it. The header isn't working. I can't seem to figure out why.If i leave the form empty, the error string is showing up properly. I used md5 encryption for the password. I concatenated the md5 of id in the database with the password and md5 encrypted the resulting string.
Try this will may help you,
if ($hashedPassword == $row['password']) {
$_SESSION['id'] = $row['id'];
header("Location: after_login.php");
die();
}

Php, MySql And Webform

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>

It say {"success":0,"message":"Database Error2. Please Try Again!"} [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
<?php
require("config.inc.php");
//if posted data is not empty
if (!empty($_POST)) {
if (empty($_POST['username']) || empty($_POST['password'])) {
// Create some data that will be the JSON response
$response["success"] = 0;
$response["message"] = "Please Enter Both a Username and Password.";
die(json_encode($response));
}
else if (empty($_POST['name']) || empty($_POST['mobilenumber']) || empty($_POST['address']) || empty($_POST['city']) || empty($_POST['state'])) {
// Create some data that will be the JSON response
$response["success"] = 0;
$response["message"] = "Please Enter the required marked ** field.";
die(json_encode($response));
}
else if (strlen($_POST['password']) < 6) {
$response["success"] = 0;
$response["message"] = "Your password should be at least 6 characters.";
die(json_encode($response));
}
else if ($_POST['password'] != $_POST['confirmpassword']){
$response["success"] = 0;
$response["message"] = "Confirm Password is not the same with Password you have entered.";
die(json_encode($response));
}
$query = " SELECT 1 FROM user WHERE email = :email";
$query_params = array(
':email' => $_POST['username']
);
//Now let's make run the query:
try {
// These two statements run the query against your database table.
$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));
}
//fetch is an array of returned data. If any data is returned,
//we know that the username is already in use, so we murder our
//page
$row = $stmt->fetch();
if ($row) {
// For testing, you could use a die and message.
//die("This username is already in use");
//You could comment out the above die and use this one:
$response["success"] = 0;
$response["message"] = "I'm sorry, this username is already in use";
die(json_encode($response));
}
$query = "INSERT INTO user ( name, email, password, mobilenumber, address, city, postcode, state) VALUES ( ;name, :email, :password, :mobilenumber, :address, :city, :postcode, :state) ";
//Again, we need to update our tokens with the actual data:
$query_params = array(
':name' => $_POST['name'],
':email' => $_POST['username'],
':password' => $_POST['password'],
':mobilenumber' => $_POST['mobilenumber'],
':address' => $_POST['address'],
':city' => $_POST['city'],
':postcode' => $_POST['postcode'],
':state' => $_POST['state']
);
//time to run our query, and create the user
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:
$response["success"] = 0;
$response["message"] = "Database Error2. Please Try Again!";
die(json_encode($response));
}
//If we have made it this far without dying, we have successfully added
//a new user to our database. We could do a few things here, such as
//redirect to the login page. Instead we are going to echo out some
//json data that will be read by the Android application, which will login
//the user (or redirect to a different activity, I'm not sure yet..)
$response["success"] = 1;
$response["message"] = "Username Successfully Added!";
echo json_encode($response);
//for a php webservice you could do a simple redirect and die.
//header("Location: login.php");
//die("Redirecting to login.php");
} else {
?>
<h1>Register</h1>
<form action="register.php" method="post">
Name:<br />
<input type="text" name="name" value="" />
<br /><br />
Email:<br />
<input type="text" name="username" value="" />
<br /><br />
Password:<br />
<input type="password" name="password" value="" />
<br /><br />
Confirm Password:<br />
<input type="password" name="confirmpassword" value="" />
<br /><br />
Mobile Number:<br />
<input type="text" name="mobilenumber" value="" />
<br /><br />
Address:<br />
<input type="text" name="address" value="" />
<br /><br />
City:<br />
<input type="text" name="city" value="" />
<br /><br />
Postcode:<br />
<input type="text" name="postcode" value="" />
<br /><br />
State:<br />
<input type="text" name="state" value="" />
<br /><br />
<input type="submit" value="Register New User" />
</form>
<?php
}
?>
This is the message I got back
{"success":0,"message":"Database Error2. Please Try Again!"}
I dont know what kind of exceptional the program catch... , Anyone help me out please?
It is very much appreciate of you all help.
If needed any else coding i can give it here.
$query = "INSERT INTO user ( name, email, password, mobilenumber, address, city, postcode, state) VALUES ( ;name, :email, :password, :mobilenumber, :address, :city, :postcode, :state) ";
change to
$query = "INSERT INTO user ( name, email, password, mobilenumber, address, city, postcode, state) VALUES ( :name, :email, :password, :mobilenumber, :address, :city, :postcode, :state) ";

Categories