password_verify() doesnt work when fetch from database - php

What wrong with my code? please need some help cause I dont see any problem. but still password_verify doesnt work.
public function login($username, $password){
global $db;
$sql = 'SELECT id,password FROM '.DB_PREFIX.'admin WHERE username="'.$username.'"';
$result = $db->query($sql);
$row = $result->fetch_assoc();
$pass = $row['password'];
if (password_verify($password,$pass)) {
echo "Valid";
}else{
echo "Invalid";
}
}
This is the password hashing and then save to DB
public function addnewadmin($username,$password)
{
global $db;
$hash = password_hash($password, PASSWORD_DEFAULT);
$sql = "INSERT INTO admin (username, password) VALUES ('".$username."', '".$hash."')";
$result = $db->query($sql);
return true;
}

Let's do this properly.
First, use prepared statements to get rid of SQL injection:
$stmt = 'SELECT id,password FROM '.DB_PREFIX.'admin WHERE username = ?';
$stmt->execute($username);
Then, and I guess that was the problem, fetch the result.
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$pass = $row['password'];
And now, you can verify the password.

Related

Where to place password_verify() in php when logging in and have the registeration.php in an exernal file

I am trying to create a login.php script which uses password_verify() encryption. None of the topics were clear and the problem is that in every example it looks like this
$password = '123';
$hashed = '$2y$10$Lz6eWEzHqhNhiPkNYX/LAOfP.1zuyYJSc4u66TvF1bce9WrSbnSJK';
$ver_pass = password_verify($password, $hashed){..}
Now for me the thing is that i am trying to retrieve the hashed password from a database and not from an internal hardcoded string.
My sample code:
login.php
$password = mysqli_real_escape_string($database, $password);
//Check username and password from database
$query =
"SELECT id FROM `register`
WHERE `username` = '$username'
AND `hashed_p` = '$password'";
$result = mysqli_query($database,$query);
$row = mysqli_fetch_array($result,MYSQLI_ASSOC);
//If username and password exist in our database then create a session.
$verified_password = password_verify($password, $hashed_password);
if(mysqli_num_rows($result) && $verified_password){
echo start session succesfully
}else{ echo error}
}
register.php
$password = mysqli_real_escape_string($database, $password);
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$query = "SELECT email FROM register WHERE email='$email'";
$result = mysqli_query($database, $query);
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
$query = mysqli_query($database,
"INSERT INTO `register` (`hashed_p`) VALUES ('".$hashed_password."')";
if ($query) {....}
By the way. The registration process is successful and the password_hash() works fine in the register.php file.
But in the login.php file I don't know how to retrieve the hashed password from the database and use it to verify it.
You need to Select id & password without checking for password. Then you check if the pwdHash from db ($row['hashed_p']) matches the one the user gave via password_verify:
$password = // the password in it's raw form how the user typed it. like $_POST['password'];
//Check username (without password) from database
$query =
"SELECT id, hashed_p FROM `register`
WHERE `username` = '$username'";
$result = mysqli_query($database,$query);
$row = mysqli_fetch_array($result,MYSQLI_ASSOC);
$verified_password = password_verify($password, $row['hashed_p']);
if(mysqli_num_rows($result) && $verified_password){
echo 'start session succesfully';
} else {
echo 'error';
}
BUT please change to a prepared statements (because your version is very unsecure. could easily be hacked. Just seach for 'Bobby Tables'.):
$stmt = mysqli_prepare($database, $query);
mysqli_stmt_bind_param ($stmt, 's', $username);
$success = mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);

Getting hashed password with prepared statements

I can't get this to work. I am new to working with prepared statements so i i'm kinda 50/50 on what i'm doing.
Upon registration, the password is hashed with password_hash($pass,PASSWORD_DEFAULT)
Now, i'm trying to get my login page to function with this but i dont know where / how to write it with the password_verify()
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT * FROM users WHERE BINARY username=? AND password=?";
$stmt = $db->prepare($sql);
$stmt->bind_param("ss",$username,$password);
$stmt->execute();
$result = $stmt->get_result();
$num_rows = $result->num_rows;
if($num_rows == 1){
$rows = $result->fetch_assoc();
if(password_verify($password, $rows['password'])){
$_SESSION['loggedin'] = $username;
$_SESSION['country'] = $rows['country'];
$_SESSION['email'] = $rows['email'];
$_SESSION['avatar'] = $rows['u_avatar'];
$_SESSION['is_gm'] = $rows['is_gm'];
$_SESSION['user_lvl'] = $rows['user_lvl'];
$_SESSION['totalposts'] = $rows['post_total'];
$_SESSION['totalcoins'] = $rows['coins_total'];
$_SESSION['totalvotes'] = $rows['vote_total'];
$_SESSION['secquest'] = $rows['sec_quest'];
$_SESSION['secanswer'] = $rows['sec_answer'];
$_SESSION['join_date'] = $rows['join_date'];
header("Location: /index.php");
exit();
}
} else {
echo "<p class='error_msg'>No accounts could be found with the given credentials.</p>";
}
$stmt->free_result();
$stmt->close();
$db->close();
I would assume that the password verify would before if($num_rows == 1) but as i said, i have no idea.
Your query is essentially:
SELECT * FROM users WHERE username=username AND password_hash=plain_text_password
This isn't going to work. If you're relying on PHP password hashing, you can't do a password comparison on the SQL level. Retrieve the password hash from the database then do the password_verify (exclude the password=?) in your WHERE arguments.

Password_verify in PHP

So I'm enabling users to create accounts with a username and password. I have managed to encrypt the password when a user creates a new account using:
$hash = password_hash($password, PASSWORD_BCRYPT);
However I'm having trouble with password_verify when logging in, could someone please help me with what I have? I know it's something like this:
password_verify($password, $hash)
But I don't know how to structure it or where to add it in the code. Thanks in advance. This is what I have:
<?php
if (isset($_GET["username"]) && isset($_GET["password"]) ){
$username = $_GET["username"];
$password = $_GET["password"];
$result = login( $username, $password);
echo $result;
}
function makeSqlConnection()
{
$DB_HostName = "";
$DB_Name = "";
$DB_User = "";
$DB_Pass = "";
$con = mysql_connect($DB_HostName,$DB_User,$DB_Pass) or die(mysql_error());
mysql_select_db($DB_Name,$con) or die(mysql_error());
return $con;
}
function disconnectSqlConnection($con)
{
mysql_close($con);
}
function login($username, $password)
{
$con = makeSqlConnection();
$sql = "select * from login where username = '$username' and password = '$password';";
$res = mysql_query($sql,$con) or die(mysql_error());
$res1 = mysql_num_rows($res);
disconnectSqlConnection($con);
if ($res1 != 0) {
return 1;
}else{
return 0;
}// end else
}// end of Function
?>
The general practice is as follows:
Fetch password hash from the database where the username = the inputted username.
If rows are found, then there's a user
Now you compare the inputted password against the hash stored in the database.
I'll outline the above flow in some pseudo code for you here:
$query = SELECT password FROM users WHERE username = '$username'
$data = FETCH_THE_DATA($query);
if(password_verify($USER_INPUTTED_PASSWORD, $data['password'])) {
// password is correct
} else {
// password is in-correct
}
Notes
Stop using mysql_* functions. The library is deprecated as it's unreliable and will be removed in future releases of PHP.
You're better off using PDO or MySQLi Prepared Statements
You should always read the manual - password_verify(), it states clearly that you compare the "user inputted password" against the hashed version which is stored in your database.
Since I'm feeling good and sleepy today, I'll write a bunch of codes.
This is an example how to use PDO with prepared statement. You will have to tweak it according to your needs and you have to check if the post/get not empty as well.
I prefer to use POST request for login so this example will use POST request..
This is my user class. Which use placeholders and binding instead of passing the parameters into the query directly. This will give some protections against SQL injection attack.
class User{
private $dbh;
function __construct(){
$this->dbh = new PDO("mysql:host=".DB_SERVER.";dbname=".DB_NAME.';charset=utf8mb4', DB_USER, DB_PASSWORD) or die('db connect error');
}
function create($username, $password){
$status = false;
try{
$stmt = "INSERT INTO login (username, password)
VALUES (?, ?)";
$qry = $this->dbh->prepare($stmt);
$qry->bindParam(1, $username);
$qry->bindParam(2, $password);
$status = $qry->execute();
}catch(PDOException $e){
$e->getMessage();
}
$qry->closeCursor();
return $status;
}
public function getPassword($username){
$status = false;
try{
$stmt = "SELECT * FROM login WHERE username = ? LIMIT 1";
$qry = $this->dbh->prepare($stmt);
$qry->bindParam(1, $username);
$qry->execute();
$status = $qry->fetch(PDO::FETCH_ASSOC);
}catch(PDOException $e){
$e->getMessage();
}
$qry->closeCursor();
return $status;
}
}
This is how to create the user. Note that I don't check if the username already exist. You can either implement it yourself or use unique index on username column provided that the collation is case insensitive.
I have also increased the cost from the default that is 10 and I defined PASSWORD_DEFAULT to be used because I want the PHP engine to always use the strongest available algorithm (currently bcrypt).
function hashPassword($password){
$password = password_hash($password, PASSWORD_DEFAULT,array('cost' => 16));
return $password;
}
$user = new User;
$_POST['password'] = hashPassword($_POST['password']);
if(!$user->create(trim($_POST['username']),$_POST['password'])){
echo 'Failed creating user';
}else{
echo 'User created';
}
This is how to verify the password.
$user = new User;
$getPassword = $user->getPassword(trim($_POST['username']));
if(!$getPassword){
echo 'Error fetching user';
}else{
if(!password_verify($_POST['password'], $getPassword['password'])){
echo 'Login failed';
}else{
echo 'Login successful';
}
}

Prepared statement for login function PHP

I am trying to write a parametrised login function in PHP.
The function should get the $id and $pass bind and execute statement and return an associative array from the database with $id, $password, $user_first_name.
Checking for user id and password validation, if true the session should start and set the session with the username from the database.
For some reason I can't get this working. Any suggestions?
Thanks!
public function logIn($id, $password)
{
$stmt = $this->link->prepare("SELECT user_id, user_name, user_password FROM Users WHERE user_id = ? ");
$stms->bind_param('i', $user_id);
if ($stmt->execute())
{
$result = $stmt->get_result();
while($row = $result->fetch_array(MYSQLI_ASSOC))
{
$dbuser_id = $row['user_id'];
$dbpassword = $row['user_password'];
$dbuser_first_name = $row['user_first_name'];
}
if($id == $dbuser_id and $password == $dbpassword)
{
session_start();
$_SESSION['session_user_first_name'] = $dbuser_first_name;
}
else
{
session_unset();
echo "Credentials do not match";
}
}
}
You have
$stms->bind_param('i', $user_id);
But your function signature is:
public function logIn($id, $password)
So you probably want:
$stms->bind_param('i', $id);
Have a look at $stms->bind_param('i', $user_id);:
stms should be stmt
$user_id should be $id
...

PHP login function not working when I enable sha1

I have a PHP page that registers and logs in users. When I enable sha1, the user gets created and the encrypted password is stored in the DB, but they cannot log in. When I comment out the line to encrypt in both the user creation section as well as the login section, everthing works. Here is my code to create the user:
function add_member($nick_name, $email_address, $password) {
global $db;
$password = sha1($password);
$query = "INSERT INTO members
(nick_name, email_address, password)
VALUES
('$nick_name', :email_address, :password)";
$statement = $db->prepare($query);
$statement->bindValue(':email_address', $email_address);
$statement->bindValue(':password', $password);
$statement->execute();
$statement->closeCursor();
}
Here is my code to validate the user:
function is_valid_member($email_address, $password) {
global $db;
$password = sha1($password);
$query = "SELECT member_ID
FROM members
WHERE email_address = :email_address AND password = :password";
$statement = $db->prepare($query);
$statement->bindValue(':email_address', $email_address);
$statement->bindValue(':password', $password);
$statement->execute();
$valid = ($statement->rowCount() == 1);
$statement->closeCursor();
return $valid;
}
Again, when I comment out the "$password = sha1($password);" in both sections, everything works but the password is clear text.
Thanks!
try to debug like this, echo your $password = sha1($password); and check your database entry, might be your datatype length truncated some text in stored password

Categories