How to change this part of code as PHP prepared statement? - php

Statement
In login_check.php, it worked but I would like to change it into the prepared statement.
login.php
<body>
<div class="container">
<h1>Please Log In to the System</h1>
<form method="post" action="login_check.php">
<input type="text" name="username" placeholder="Username" required>
<input type="password" name="password" placeholder="Password" autocomplete="off" required>
<button type="submit" name="login" value="Log In">Log In</button>
</form>
</div>
</body>
login_check.php
<body>
<?php
//Establish connection
include 'connection.php';
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
$sql = "SELECT * FROM admins WHERE admin_username = '".mysqli_real_escape_string($conn, $_POST['username'])."' and admin_password = '".mysqli_real_escape_string($conn, $_POST['password'])."'";
$query = mysqli_query($conn, $sql);
$result = mysqli_fetch_array($query);
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
if(!$result) //Username or Password is invalid!
{
?>
<div class="container">
<h1>Username or Password is invalid!</h1>
<form method="post" action="login.php">
<button type="submit">Back</button>
</form>
</div>
<?php
}
else //Username and Password are valid!
{
$_SESSION["admin_id"] = $result["admin_id"];
$_SESSION["admin_username"] = $result["admin_username"];
session_write_close();
header("location:front.php");
}
$conn->close();
?>
</body>

To change to prepared statements, you just need to
replace variables in your query with a ?
prepare the query
bind variables to the parameters
execute the statement
For your code that would look like this:
$sql = "SELECT * FROM admins WHERE admin_username = ? and admin_password = ?";
$stmt = $conn->prepare($sql) or die($conn->error);
$stmt->bind_value("ss", $_POST['username'], $_POST['password']);
$stmt->execute() or die($stmt->error);
$result = $stmt->get_result();
Note that you should not be storing passwords in plain text in your database. Please look into PHPs password_hash and password_verify functions to properly handle your passwords. You would use password_hash when storing the password in the database, and then your code for verifying the user would look something like:
$sql = "SELECT * FROM admins WHERE admin_username = ?";
$stmt = $conn->prepare($sql) or die($conn->error);
$stmt->bind_value("s", $_POST['username']);
$stmt->execute() or die($stmt->error);
$result = $stmt->get_result() or die($stmt->error);
$row = $result->fetch_array();
if (!$row|| !password_verify($_POST['password'], $row['admin_password']) {
// invalid username or password

login_check.php
<?php
//Establish connection
include 'connection.php';
$sql = "SELECT * FROM admins WHERE admin_username = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s",$_POST['username']);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_array())
{
$hash = password_hash($_POST['password'],PASSWORD_DEFAULT);
mysqli_query($conn,"UPDATE admins SET admin_password = '$hash' WHERE admin_id='{$row['admin_id']}");
}
if(!$row || !password_verify($_POST['password'],$row['admin_password']))
{
?>
<div class="container">
<h1>Username or Password is invalid!</h1>
<form method="post" action="login.php">
<button style="font-size: 30px" type="submit" class="btn btn-dark"><b>Back</b> <i class="fas fa-arrow-alt-circle-left"></i></button>
</form>
</div>
<?php
}
else
{
$_SESSION["admin_id"] = $result["admin_id"];
$_SESSION["admin_username"] = $result["admin_username"];
session_write_close();
header("location:front.php");
}
$stmt->close();
$conn->close();
?>
</body>
There is no syntax error shown up but I think there are some mistakes in
=> mysqli_query($conn,"UPDATE admins SET admin_password = '$hash' WHERE admin_id ='{$row['admin_id']}");
=> if(!$row || !password_verify($_POST['password'],$row['admin_password']))
Form this code, the result is it always returns as username or password is invalid, even I put the valid ID and Password.

Related

Notice: Trying to get property 'num_rows' of non-object

I'm reworking a login form to PDO based with OOP in mind. And I am running into the error given above. So I have two files one is an login.php and one is an included file called functions.inc.php
The code for the login.php is as follows.
<?php
include_once("includes/functions.inc.php");
// get username and password from $_POST
if(!empty($_POST)){
$username = $_POST['email'];
$password = $_POST['password'];
// check if a user can login (function)
if(canilogin($username, $password)){
session_start();
$_SESSION['username'] = $username;
$_SESSION['loggedin'] = true;
header('Location: index.php');
}
else{
$error = true;
// if no -> $error tonen
}
}
?><!DOCTYPE html>
<html lang="en">
<body class="login">
<div class="grid container_login">
<div class="login_grid">
<form class="form_login" action="" method="post">
<?php if( isset($error) ): ?>
<div class="form__error">
<p>
Sorry, we can't log you in with that email address and password. Can you try again?
</p>
</div>
<?php endif;?>
<div>
<label for="email">EMAIL</label><br/>
<input type="text" id="email" name="email" placeholder="Lucasdebelder#snapshot.be" required>
</div>
<div>
<label for="password">PASSWORD</label><br/>
<input type="password" id="password" name="password" placeholder="Atleast 8 characters" required>
</div>
<div>
<input type="submit" value="LOG IN" class="btn_login">
</div>
<p class="center_align">Or</p>
<br/>
<a class="center_align" href="register.php">Register here.</a>
</form>
</div>
</body>
</html>
And the functions.inc.php where the error is happening, to be precise it happens at if($result->num_rows != 1){.
Also the first few lines were the once that worked before but that is done with real escape string to secure against SQL inject but it's kinda a wacky way to do and I decided to try to rework it to PDO.
<?php
function canilogin( $username, $password){
/* THIS IS THE OLD WAY THAT WORKED/WORKS
$conn = new mysqli("localhost", "root", "root", "snapshot");
$query = "select * FROM users WHERE email='".$conn->real_escape_string($username). "'";
$result = $conn->query($query);
*/
$conn = new PDO('mysql:host=localhost; dbname=snapshot', 'root', 'root');
//$query = "select * FROM users WHERE email='".$conn->real_escape_string($username). "'";
$statement = $conn->prepare("select * from users where email = :username");
$statement->bindValue(':username', $username);
$statement->execute();
$result = $statement->execute();
if($result->num_rows != 1){
return false;
}
$user = $result->fetch_assoc();
if(password_verify($password, $user['password'])){
return true;
}
else{
return false;
}
}
?>
The reason you are having the issue is that $result is not correct. Once $statement->execute(); is executed it becomes a PDOStatement object.
First of all remove $result = $statement->execute(); and try
if($statement->rowCount() != 1){
return false;
}
$user = $statement->fetch();
if(password_verify($password, $user['password'])){
return true;
}
else{
return false;
}

password_verify() expects parameter 2 to be string

Getting this error during attempt to login to member account:
Fatal error: Uncaught TypeError: password_verify() expects parameter 2 to be string, null given in C:\xampp\htdocs\e_id\login.php:77
Stack trace:
#0 C:\xampp\htdocs\e_id\login.php(77): password_verify('password', NULL)
#1 {main} thrown in C:\xampp\htdocs\e_id\login.php on line 77
<?php
/*
ERROR HANDLING
*/
declare(strict_types=1);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
include 'config.php';
// check if user is already logged in
if (is_logged() === true)
{
//Redirect user to homepage page after 5 seconds.
header("refresh:2;url=home.php");
exit;
}
if ($_SERVER['REQUEST_METHOD'] == "POST")
{
if (isset($_POST["login_username_or_email"]) &&
isset($_POST["login_password"]))
{
$username_or_email = trim($_POST["login_username_or_email"]);
$password = $_POST["login_password"];
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
//Select Username or Email to check against Mysql DB if they are
already registered or not.
$stmt = mysqli_stmt_init($conn);
$stmt = mysqli_prepare($conn, "SELECT usernames, emails FROM
users WHERE usernames = ? OR emails = ?");
mysqli_stmt_bind_param($stmt, 'ss', $username,
$email_confirmation);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
*/
if(strpos("$username_or_email", "#") === true)
{
$email = $username_or_email;
$username = "";
$stmt = mysqli_prepare($conn, "SELECT emails FROM users
WHERE emails = ?");
mysqli_stmt_bind_param($stmt, 's', $email);
}
else
{
$username = $username_or_email;
$email = "";
$stmt = mysqli_prepare($conn, "SELECT usernames FROM
users WHERE usernames = ?");
mysqli_stmt_bind_param($stmt, 's', $username);
}
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
printf("%s (%s)\n",$row["usernames"],$row["passwords"]);
var_dump($row);
// Check if inputted Username or Email is registered or not.
if (!$result) // either this paragraph or ...
{
echo Incorrect User Credentials!";
exit;
}
elseif (password_verify($password, $row['passwords']))
{
if($row['accounts_activations_statuses'] == '0')
{
echo "You have not activated your
account yet! Check your email for instructions
.";
exit;
}
}
else
{
//If 'Remember Me' check box is checked then set the
cookie.
//if (isset($_POST['login_remember']) &&
$_post['login_remember'] == "on")
{
setcookie("login_username", $username, time()+
(10*365*24*60*60));
}
else
{
//If Cookie is available then use it to auto log
user into his/her account!
if (isset($_COOKIE['login_username']))
{
setcookie("login_username","","");
}
}
$_SESSION["user"] = $username;
header("location:home.php?user=$username");
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title><?php $site_name?> Member Login Page</title>
<meta charset="utf-8">
</head>
<body>
<div class = "container">
<form method="post" action="">
<center><h3><?php $site_name ?> Member Login Form</h3></center>
<div class="text-danger">
<div class="form-group">
<center><label>Username/Email:</label>
<input type="text" placeholder="Enter Username" name="login_username_or_email" value="<?php if(isset($_COOKIE["login_username_or_email"])) echo $_COOKIE["login_username_or_email"]; ?>"</center>
</div>
<div class="form-group">
<center><label>Password:</label>
<input type="password" placeholder="Enter password" name="login_password" value="<?php if(isset($_COOKIE["login_password"])) echo $_COOKIE["login_password"]; ?>"></center>
</div>
<div class="form-group">
<center><label>Remember Login Details:</label>
<input type="checkbox" name="login_remember" /></center>
</div>
<div class="form-group">
<center><input type="submit" name="login_submit" value="Login" class="button button-success" /></center>
</div>
<div class="form-group">
<center><font color="red" size="3"><b>Forgot your password ?</b><br>Reset it here!</font></center>
<center><font color="red" size="3"><b>Not registered ?</b><br>Register here!</font></center>
</form>
</div>
</body>
</html>
</pre>
Apart from all the syntax shenanigans, you're not returning the password from the query:
$stmt = mysqli_prepare($conn, "
SELECT usernames FROM users WHERE usernames = ?"
);
So it will be null
You need to fetch password column also from db
if(strpos("$username_or_email", "#") === true)
{
$email = $username_or_email;
$username = "";
$stmt = mysqli_prepare($conn, "SELECT emails,passwords FROM users
WHERE emails = ?"); //<---Add passwords in select
mysqli_stmt_bind_param($stmt, 's', $email);
}
else
{
$username = $username_or_email;
$email = "";
$stmt = mysqli_prepare($conn, "SELECT usernames,passwords FROM
users WHERE usernames = ?"); //<---Add passwords in select
mysqli_stmt_bind_param($stmt, 's', $username);
}

PHP - multi user login unable to detect type of user

I wanted to make a multi user login. At least 2 type of users that is admin and a user. When I tried to enter the username and password as an admin, got the error displayed as 'Username and Password Invalid' instead. Same for user.
PHP
include_once 'config.php';
$error="";
if(isset($_POST['login'])){
if(empty($_POST['username']) || empty($_POST['password'])){
$error = '<div class="alert alert-danger">Username or Password is Invalid</div>';
} else {
$username= $_POST['username'];
$password= $_POST['password'];
$stmt = $con->prepare("SELECT * FROM users WHERE username=? AND password=? ");
$stmt->bind_param("ss",$username,$password);
$stmt->execute();
$row = $stmt->fetch();
$user = $row['username'];
$pass = $row['password'];
$id = $row['id'];
$type = $row['typeuser'];
if ($username==$user && $pass==$password){
session_start();
$_SESSION['username']=$user;
$_SESSION['passsword']=$pass;
$_SESSION['id']=$id;
$_SESSION['typeuser']=$type;
if($type=='admin'){
header("Location: dashboard.php");
} else if ($type=='user'){
header("Location: user_dashboard.php");
}
} else
{
$error = "Username or Password is Invalid";
}
}
mysqli_close($con); // Closing connection
}
?>
FORM
<form role="form" method="post" action="" >
<div class="page-content container">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="login-wrapper">
<div class="box">
<div class="content-wrap">
<h6>Sign In</h6>
<input class="form-control" type="text" placeholder="Username" id="username" name="username"><br/>
<input class="form-control" type="password" placeholder="Password" id="password" name="password"><br/>
<input class="btn btn-primary btn-lg" type="submit" value="Login" name="login"><br><br>
<strong class = "text-danger"><?php echo $error; ?></strong>
</div>
</div>
<div class="already">
<p>Don't have an account yet?</p>
Sign Up
</div>
</div>
</div>
</div>
</div>
</form>
I don't know why this error is displayed since I did the code right.
mysqli execute and fetch is not same as pdo when you use
execute in mysqli you need to use fetch with bind_result. Try follwoing code/ change your
$stmt = $con->prepare("SELECT * FROM users WHERE username=? AND password=? ");
$stmt->bind_param("ss",$username,$password);
$stmt->execute();
$row = $stmt->fetch();
$user = $row['username'];
$pass = $row['password'];
$id = $row['id'];
$type = $row['typeuser'];
To
$stmt = $con->prepare("SELECT username,password,id,typeuser FROM users WHERE username=? AND password=? ");
$stmt->bind_param("ss",$username,$password);
$stmt->execute();
$stmt->bind_result($user, $pass,$id,$type);
$stmt->fetch();

PHP Prepared statements - Failing to retrieve the string from the database

I'm still fairly new to the prepared statements because it was brought to my attention by another user. I've been able to create a registration function that properly prepares the statement, binds it and then executes it. It goes into the database just fine. However, I'm not sure I understand how the login part would work. I'm trying to fetch a row and the result I keep getting is "1" but not the row + data inside the row. Any advice?
Database:
login.php (where the form is located)
<form id="loginform" class="form-horizontal" role="form" action="" method="post">
<div style="margin-bottom: 25px" class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input id="login-username" type="text" class="form-control" name="Lusername" placeholder="Username or Email">
</div>
<div style="margin-bottom: 25px" class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input id="login-password" type="password" class="form-control" name="Lpassword" placeholder="Password">
</div>
<div class="input-group">
<div class="checkbox">
<label>
<input id="login-remember" type="checkbox" name="remember" value="1"> Remember me
</label>
</div>
</div>
<div style="margin-top:10px" class="form-group">
<!-- Button -->
<div class="col-sm-12 controls">
<button id="btn-login" type="submit" class="btn btn-success"><i class="icon-hand-right"></i>Submit</button>
</div>
</div>
</form>
script:
<script type="text/javascript">
$(function() {
$("#loginform").bind('submit',function() {
var username = $('#login-username').val();
var password = $('#login-password').val();
$.post('scripts/loginFunction.php',{username:username, password:password}, function(data){
$('#signupsuccess').show();
}).fail(function(){{
$('#signupalert').show();
}});
return false;
});
});
</script>
loginFunction.php
<?php
require 'connection.php';
$username = $_POST['username'];
$password = $_POST['password'];
if($conn->connect_error){
die("Connection failed: " . $conn->connect_error);
}
$stmt = $conn->prepare("SELECT `Username`, `Password` FROM `users` WHERE `Username` = ?");
$stmt->bind_param('s',$username);
$stmt->execute();
$stmt->store_result();
echo $stmt->num_rows;
/*if($stmt->num_rows == 1){
$result = $stmt->get_result();
$row = $result->fetch_assoc();
print_r($row);
// here is where you could verify the password
if(password_verify($password, $row['Password'])) {
// good password
echo 'all good!';
}
} else {
//echo "failed to find row";
}*/
?>
loginFunction.php that does work and queries the database properly
require 'connection.php';
$username = $_POST['username'];
$password = $_POST['password'];
if($conn->connect_error){
die("Connection failed: " . $conn->connect_error);
}
$query = "SELECT * FROM users WHERE username='$username'";
$result = $conn->query($query);
if($result->num_rows == 1){
$row = mysqli_fetch_array($result);
if(password_verify($password, $row['Password'])){
echo "Login successful!";
}
else{
echo "Login failed.";
}
}
EDIT: Here is the code you should use. Note how $stmt is carried throughout:
$stmt = $conn->prepare("SELECT `Username`, `Password` FROM `users` WHERE `Username` = ?");
$stmt->bind_param('s',$username);
$stmt->execute();
$stmt->store_result();
echo $stmt->num_rows;
/*if($stmt->num_rows == 1){
$result = $stmt->get_result();
$row = $result->fetch_assoc();
print_r($row);
// here is where you could verify the password
if(password_verify($password, $row['Password'])) {
// good password
echo 'all good!';
}
} else {
//echo "failed to find row";
}*/
I have resolved the issue. When I went to fetch, I needed to store it in a separate variable than the one that the user is storing their entered password into. This can be reflected in the code below:
<?php
require 'connection.php';
$username = $_POST['username'];
$password = $_POST['password'];
$dbusername = ""; //These two being the new variables
$dbpassword = "";
if($conn->connect_error){
die("Connection failed: " . $conn->connect_error);
}
$stmt = $conn->prepare("SELECT Username, Password FROM users WHERE Username = ?;");
$stmt->bind_param('s', $username);
$stmt->execute();
if($stmt->execute() == true){
$stmt->bind_result($dbusername, $dbpassword);
$stmt->fetch();
if(password_verify($password, $dbpassword)) {
echo 'successful';
}
else{
echo 'failed';
}
}
else{
echo 'failed';
}
?>

Display and update user information

I new to PHP and learning to update the user information in the mysql. The problem here is I am not able to display the data on the form nor able to update the user's information. My form seems to be empty instead of having any user information
<?php
session_start();
require('config.php');
error_reporting(0);
if(isset($_POST["submit"]))
{
$sqlupdate = mysql_query("UPDATE user
SET
first_Name = '{$_POST['sname']}',
password = '{$_POST['spassword']}',
WHERE first_Name = '{$_POST['sname']}'
");
}
$sql=mysql_query("SELECT * FROM student WHERE email='$_SESSION['SESS_USEREMAIL']' and password ='$_SESSION['SESS_USERPASS']' ");
while($record = mysql_fetch_array($sql)){
$first = $record['first_Name'];
$second = $record['first_Name'];
}
?>
<form method="post" name="studentform" id="student-form" action="#" enctype="multipart/form-data">
<div class="form-group">
<div class="inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-home"></i></span>
<input name="sname" id="studentname" placeholder="Name" class="form-control" type="text" value="<?php echo $first; ?>">
</div>
</div>
</div>
<div class="form-group">
<div class="inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input name="spassword" id="studentpassword" placeholder="Password" class="form-control" type="password" value="<?php echo $second; ?>">
</div>
</div>
</div>
<div class="form-group">
<button type="submit" id="ssubmitbtn" class="btn btn-primary btn-md" value="submit" name="submit">Submit<span class="glyphicon glyphicon-pencil "></button>
</div>
</form>
Assuming that your SQL is correct, you could use PDO's as followed;
<?php
$sFirst = '';
$sLast = '';
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "SELECT * FROM user WHERE email= :email and password = :password";
$st = $conn->prepare( $sql );
$st->bindValue(":email", $name, PDO::PARAM_STR);
$st->bindValue(":password", $password, PDO::PARAM_STR);
$st->execute();
if ( $row = $st->fetch() ){
$sFirst = $row['first_col_name'];
$sLast = $row['seccond_col_name'];
}
?>
You mention setting the values in the query from a session, using the following lines you can assign what ever var to be bound to the query;
$st->bindValue(":email", $_SESSION['SESS_USEREMAIL'], PDO::PARAM_STR);
$st->bindValue(":password", $_SESSION['SESS_USERPASS'], PDO::PARAM_STR);
And for your update you could use something like;
if(isset($_POST["submit"]))
{
$sError = '';
$sName = '';
$sPassword = '';
// basic error checking
if(isset($_POST['sname']) && $_POST['sname'] != ''){
$sName = $_POST['sname'];
}
if($sName == '') $sError .= "[MissingName]";
if(isset($_POST['spassword']) && $_POST['spassword'] != ''){
$sPassword = $_POST['spassword'];
}
if($sPassword == '') $sError .= "[MissingPassword]";
// if no errors, proceed to update
if($sError == ''){
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "UPDATE user first_name = :firstName, password = :password WHERE first_name :first_name";
$st = $conn->prepare( $sql );
$st->bindValue(":firstName", $_POST['sname'], PDO::PARAM_STR);
$st->bindValue(":password", $_POST['spassword'], PDO::PARAM_STR);
$st->execute();
}
}
Before updating I would check/validate the information entered is expected.
I would also use a Unique Identifier when updating to ensure the correct user is updated. For this I normally create a trigger on the table that will generate a short unique code.
$sql=mysqli_query("SELECT * FROM user WHERE email='$useremail' and password ='$userpassword' ");
$record = mysqli_fetch_array($sql);
instead write <?php echo $first... use <?php echo $redord['firstname] ;?>
This shoud solve your problem.
P.S
$useremail and $userpassword must stored in a session (in login page)
USE:
$_SESSION['usermail'] = $usermail;
$_SESSION['userpassword'] = $userpassword;
IN QUERY
$sql=mysql_query("SELECT * FROM user WHERE email='$useremail' and password ='$userpassword' ");
replace $usermail with $_SESSION['username']; and $userpassword with $_SESSION['userpassword'];

Categories