ok so ive got password_hash working on one of my pages.
I'm wondering how would i apply password_verify to the following code:
function selectUser($conn, $username, $password)
{
$query = "SELECT username, password FROM login WHERE password = :password AND username = :username";
$stmt = $conn->prepare($query);
$stmt->bindValue(':username', $username);
$stmt->bindValue(':password', $password);
$stmt->execute();
if ($row = $stmt->fetch()) {
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
echo "Welcome, you are now logged in as " . $username;
return true;
}
else {
//echo "Your details were not found";
return false;
}
tried it myself and its been very confusing to me.
thank you
also got this:
if(!isset($_POST["Login"]))
{
header("Location:new-user.php");
}
$username=trim($_POST['username']);
$password=$_POST['password'];
$username= htmlspecialchars($username);
$validForm = true;
if (empty($_POST["username"]))
{
$validForm=false;
}
if (empty($_POST["password"]))
{
$validForm=false;
}
if (!$validForm) {
$error = "please ensure all fields are filled in";
include("add.php");
return false;
}
$conn=getConn();
$successLogin=selectUser($conn,$username,$password);
if($successLogin)
{
header( "Location: search.php" );
}else{
$error = "The details you have entered are incorrect";
include("add.php");
}
$conn=NULL; //close the connection
Update
also tried this: Knowing this doesnt work, tested with echo statements but still no luck
function hash_input() {
$password = "sfafgsd";
return $password = password_hash($_POST['password'], PASSWORD_BCRYPT);
}
function selectUser($conn, $username, $password)
{
$query = "SELECT password FROM login WHERE username = :username";
$stmt = $conn->prepare($query);
$stmt->bindValue(':username', $username);
$stmt->execute();
echo $username . " " . $password;
if ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
echo "WE MADE IT";
if(password_verify(hash_input($password), $row['password'])){
$_SESSION['username'] = $username;
echo "Welcome, you are now logged in as " . $username;
return true;
}
//echo "Your details were not found";
sleep(1);
return false;
}
else
{
//echo "Your details were not found";
return false;
}
}
The comments given by Mark cover the below exactly.
Order of events:
Send username to database and collect the hashed password from the row found.
run the password string given through password_verify to compare with the hashed value
return this result (true/false).
Celebrate. Have a coffeee or a tea.
There is no need to $_SESSION password data and this is a bad idea. Password data (hash or plaintext) should not be retained beyond this function call. If you do for some reason need to have a nonce value associated with this account/membership/login then this should be setup using a random string in its own column in the database.
Improved Function Code
function selectUser($conn, $username, $password)
{
$query = "SELECT password FROM login WHERE username = :username LIMIT 1";
$stmt = $conn->prepare($query);
$stmt->bindValue(':username', $username);
// $stmt->bindValue(':password', $password); NO Don't do this.
$stmt->execute();
if ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
if(password_verify($password,$row['password'])){
$_SESSION['username'] = $username;
// $_SESSION['password'] = $password; DO NOT DO THIS
echo "Welcome, you are now logged in as " . $username;
return true;
}
//bad password
//echo "Your details were not found";
sleep(1); // it can be a good idea to add a forced pause on
// password fail to discourage brute force cracking.
return false;
}
//echo "Your details were not found";
return false;
}
Related
Please, help me look at this code for login, I want to verify if input password matches stored harsh password. This does not work. If i comment out If (password_verify..., i will be able to login otherwise, it wont login. i dont know where i got the code wrong and it doesnt want to verify password before login
if (isset($_POST['agentlogin-btn'])) {
$username= $_POST['username'];
$password = $_POST['password'];
function Is_email($user)
{
//If the username input string is an e-mail, return true
if (filter_var($user, FILTER_VALIDATE_EMAIL)) {
return true;
} else {
return false;
}
}
//validation
if (strlen($_POST['username']) < 1) {
$_SESSION['error'] = 'email or phone number required';
header("Location:register.php");
return;
}
if (strlen($_POST['password']) < 1) {
$_SESSION['error'] = 'password required';
header("Location:register.php");
return;
}
if (!isset($_SESSION['error'])) {
$check_email = Is_email($username);
if ($check_email) {
$sql = "SELECT * FROM agent WHERE Email= :email LIMIT 1";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(
':email' => $_POST['username'],
));
} else {
$sql = "SELECT * FROM agent WHERE Phone_number= :phonenumber LIMIT 1";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(
':phonenumber' => $_POST['username'],
));
}
if ($stmt->execute()) {
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$user = $result;
if (password_verify($password], $user['Password'])) {
//login success
$stmt->close();
$_SESSION['id'] = $user['User_id'];
$_SESSION['agentid'] = $user['agent_id'];
$_SESSION['firstname'] = $user['First_name'];
$_SESSION['Surname'] = $user['Surname'];
$_SESSION['phonenumber'] = $user['Phone_number'];
$_SESSION['email'] = $user['Email'];
$_SESSION['verified'] = $user['verified'];
// set flash message
$_SESSION['success'] = "You are now logged in! Continue with your upload";
header('location: profilepage.php');
return;
} else {
$_SESSION['errors'] = "Wrong username/password";
header('Location: register.php');
return;
}
}
}
}
instead of writing $stmt->execute() two times, store the result in a variable, and at second place use that variable.
I'm using password_verify with database when I login it always say password incorrect and in my database I'm using char 255 for password.
function login(){
global $db, $username, $errors;
// grap form values
$username = e($_POST['username']);
$password = e($_POST['password']);
$userrecord1 = mysqli_query($db, "SELECT * FROM users WHERE username='$_POST[username]' LIMIT 1");
if (count($userrecord1) == 1 ) {
$urow1 = mysqli_fetch_array($userrecord1);
$hash = $urow1["password"];
}
// attempt login if no errors on form
if (count($errors) == 0) {
$passuser = password_verify($password, $hash);
$query = "SELECT * FROM users WHERE (username='$username' OR email='$username') AND password='$passuser' LIMIT 1";
$results = mysqli_query($db, $query);
if (mysqli_num_rows($results) == 1) { // user found
// check if user is admin or user
$logged_in_user = mysqli_fetch_assoc($results);
if ($logged_in_user['user_type'] == 'admin') {
$_SESSION['user'] = $logged_in_user;
$_SESSION['success'] = "Welcome admin";
header('location: /admin/home');
}else{
$_SESSION['user'] = $logged_in_user;
$_SESSION['success'] = "Welcome user";
header('location: /home/index');
}
}else {
array_push($errors, "Wrong username/password combination");
}
}
}
There's a few things I'd like to note,
Usage of the global keyword is not recommended - you should instead pass values as arguments to the function instead.
You are wide open to SQL injection - use a prepared statement
Once you have verified the password by password_verify(), the password is correct and the user has verified his login.
if (count($userrecord1) == 1 ) { doesn't make much sense, as you haven't fetched any records yet.
Your second select is moot (see point 3), and invalid as selecting from a hashed password will not yield the result.
Use exit; after header("Location: .."); calls
function login(){
global $db, $username, $errors;
// grap form values
$username = e($_POST['username']);
$password = e($_POST['password']);
$stmt = $db->prepare("SELECT password, user_type FROM users WHERE username=? LIMIT 1");
$stmt->bind_param("s", $username);
$stmt->execute();
$stmt->bind_result($dbPassword, $userType);
if ($stmt->fetch() && password_verify($password, $dbPassword)) {
if ($userType == 'admin') {
$_SESSION['user'] = $username;
$_SESSION['success'] = "Welcome admin";
header('location: /admin/home');
exit;
} else {
$_SESSION['user'] = $username;
$_SESSION['success'] = "Welcome user";
header('location: /home/index');
exit;
}
} else {
$errors[] = "Wrong username/password combination";
}
}
As recommended, I've been trying to secure my DB by using prepared statements. I have the following login that works perfectly that I'm trying to convert to prepared statement.
if(isset($_POST["Submit"])) {
$Username = mysqli_real_escape_string($con, $_POST["Username"]);
$get_hash_db = mysqli_query($con, "SELECT password FROM admin_registration WHERE username='$Username'");
$hash_db_data = mysqli_fetch_array($get_hash_db);
$hash = $hash_db_data['password'];
echo $hash;
if(password_verify($_POST['Password'], $hash)){
$Password = $hash;
}else {
$_SESSION["ErrorMessage"] = "Username or Password was incorrect";
Redirect_to("admin_login.php");
}
else {
$Found_Account = Login_Attempt($Username, $Password);
$_SESSION["User_Id"] = $Found_Account["id"];
$_SESSION["Username"] = $Found_Account["username"];
if($Found_Account) {
$_SESSION["SuccessMessage"] = "Login Successful! Welcome {$_SESSION["Username"]}";
Redirect_to("blog_admin/dashboard.php");
}else {
$_SESSION["ErrorMessage"] = "Invalid Username / Password";
Redirect_to("admin_login.php");
}
}
}
Below this it takes you into a Login_Attempt() function that look like this:
function Login_Attempt($Username, $Password) {
global $con;
$sql = "SELECT * FROM admin_registration WHERE username='$Username' AND password='$Password'";
$result = mysqli_query($con, $sql);
if($admin = mysqli_fetch_assoc($result)) {
return $admin;
}
else {
return null;
}
}
With my new prepared statements I never get past $_SESSION["ErrorMessage"] = "Invalid Username / Password"; Which tells me that I'm at least satisfying the condition $Password = $hash; Here is what I have.
if(isset($_POST["Submit"])) {
$Username = mysqli_real_escape_string($con, $_POST["Username"]);
$get_hash_db = mysqli_prepare($con, "SELECT password FROM admin_registration WHERE username = ? ");
mysqli_stmt_bind_param($get_hash_db, "s", $Username);
mysqli_stmt_execute($get_hash_db);
mysqli_stmt_bind_result($get_hash_db, $hash);
mysqli_stmt_fetch($get_hash_db);
echo $hash;
if(password_verify($_POST['Password'], $hash)){
$Password = $hash;
}else {
$_SESSION["ErrorMessage"] = "Username or Password was incorrect";
Redirect_to("admin_login.php");
}
Once I get passed this, I'm going through this:
else {
$Found_Account = Login_Attempt($Username, $Password);
$_SESSION["User_Id"] = $Found_Account["id"];
$_SESSION["Username"] = $Found_Account["username"];
if($Found_Account) {
$_SESSION["SuccessMessage"] = "Login Successful! Welcome {$_SESSION["Username"]}";
Redirect_to("blog_admin/dashboard.php");
}else {
$_SESSION["ErrorMessage"] = "Invalid Username / Password";
Redirect_to("admin_login.php");
}
}
}
but it always returns to $_SESSION["ErrorMessage"] = "Invalid Username / Password"; I'm not sure I understand why? Is it because I'm binding the param $Username, so function Login_Attempt($Username, $Password) does not handle correctly? Sorry, this is my first go at prepared statements so really struggling to understand.
so I have this site where drivers can login and register.
at the moment i can store the username in a session variable, im trying to do the same for the user_id so the user can later retrieve it when adding more details for a job.
heres what I got so far:
function selectUser($conn, $username, $password, $userID)
{
$query = "SELECT * FROM login WHERE username = :username";
$stmt = $conn->prepare($query);
$stmt->bindValue(':username', $username);
//$stmt->bindValue(':user_ID', $userID);
$stmt->execute();
if ($row = $stmt->fetch(PDO::FETCH_OBJ))
{
if (md5($password) == $row->password) {
$_SESSION['username'] = $username;
$_SESSION['user_ID'] = $userID;
// $_SESSION['password'] = $password;
echo "Welcome, you are now logged in as " . $username;
return true;
}
return false;
}
else
{
//echo "Your details were not found";
return false;
}
}
when the driver accesses another page:
<?php
if(!isset($_SESSION))
{
session_start();
}
require_once ("config.inc.php");
try
{
$conn = new PDO(DB_DATA_SOURCE, DB_USERNAME, DB_PASSWORD);
}
catch(PDOException $exception)
{
echo "Oh no, there was a problem" . $exception->getMessage();
}
if(isset($_SESSION["username"]))
{
echo "Welcome, you are now logged in as <b>".$_SESSION['username']."</b> <img class='clientView' src='images/loginIcon.png' alt='client'>"; }
else {
echo "You are currently not logged in";
}
$login = $_SESSION['user_ID'];
$query = "SELECT * FROM login WHERE user_ID = :login";
$term = $conn->prepare($query);
$term->bindValue(':login', $login);
$term->execute();
$login = $term->fetch(PDO::FETCH_OBJ);
print_r($_SESSION);
?>
tested it using print r and for some reason it doesnt seem to be collecting the user_ID.
am i doing something wrong?
upon test: https://snag.gy/6bGd5m.jpg
when calling the function:
$username=trim($_POST['username']);
$password=$_POST['password'];
$username= htmlspecialchars($username);
$validForm = true;
if (empty($_POST["username"]))
{
$validForm=false;
}
if (empty($_POST["password"]))
{
$validForm=false;
}
if (!$validForm) {
$error = "please ensure all fields are filled in";
include("add.php");
return false;
}
$conn=getConn();
$successLogin=selectUser($conn,$username,$password);
if($successLogin)
{
header( 'Location: profile.php');
}else{
$error = "The details you have entered are incorrect";
include("add.php");
}
Debug.
Where do you store the value in the session state?:
$_SESSION['user_ID'] = $userID;
Ok, so where does $userID come from?:
function selectUser($conn, $username, $password, $userID)
{
//...
Ok, so where does the function parameter come from?:
selectUser($conn,$username,$password)
Nowhere. You never supplied a value to be stored in session, so no value was stored in session.
It seems unlikely that you actually want to supply the User ID to the function. Instead, you probably want to supply just the username and password as you currently do and then get the User ID from the database. Which might look more like this:
$_SESSION['user_ID'] = $row["user_ID"];
Or perhaps:
$_SESSION['user_ID'] = $row->user_id;
Or however you get values from your $row object.
But basically the important lesson here is... When a value isn't what you expect it to be, trace back where that value came from. Chances are you have a false assumption somewhere.
I'm hashing a password using sha1 and it is successfully storing it in the database, however i cannot seem to properly check to see if the sha1 matches one that is in the database. I've tried numerous different iterations of the below code, but nothing seems to work - what am i missing?
Registration
<?php
$username = $_POST['username'];
$password = $_POST['password'];
$passwordEncrypted = sha1($password);
try {
$result = $db->prepare("INSERT INTO
user_info
SET
username = :user,
pass = :pass
");
$result->bindParam(':user', $username);
$result->bindParam(':pass', $passwordEncrypted);
$result->execute();
}
catch (Exception $e) {
echo "Could not create username";
}
if (isset($_POST['submit'])) {
foreach ($_POST as $field) {
if (empty($field)) {
$fail = true;
}
else {
$continue = false;
}
}
if ($field == $fail) {
echo "You must enter a username and/or password";
}
else {
echo "Your account has been successfully created.";
}
}
?>
Logging in
<?php
$username = $_POST['username'];
$password = $_POST['password'];
$encryptedPassword = sha1($password);
try {
$result = $db->prepare("SELECT username, pass FROM user_info WHERE username = :user AND BINARY pass = :pass");
$result->bindParam(':user', $username);
$result->bindParam(':pass', $password);
$result->execute();
$rows = $result->fetch(PDO::FETCH_NUM);
}
catch (Exception $e) {
echo "Could not retrieve data from database";
exit();
}
if ($rows) {
session_start();
$_SESSION['username'] = $_POST['username'];
$_SESSION['loggedin'] = true;
include("inc/redirect.php");
} else {
if (isset($_POST['login'])) {
echo "Username or password incorrect (passwords are case sensitive)";
}
}
?>
You need to hash the password before querying the table, not afterwards:
<?php
$username = $_POST['username'];
$password = $_POST['password'];
$passwordEncrypted = sha1($password);
try {
$result = $db->prepare("SELECT username, pass FROM user_info WHERE username = :user AND BINARY pass = :pass");
$result->bindParam(':user', $username);
$result->bindParam(':pass', $passwordEncrypted);
$result->execute();
if ($result->fetch(PDO::FETCH_NUM)) {
session_start();
$_SESSION['username'] = $_POST['username'];
$_SESSION['loggedin'] = true;
include("inc/redirect.php");
} else {
if (isset($_POST['login'])) {
echo "Username or password incorrect (passwords are case sensitive)";
}
}
}
catch (Exception $e) {
echo "Could not retrieve data from database";
exit();
}
?>