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
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;
}
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);
}
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();
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';
}
?>
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'];