Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
i have a query using PDO. password match was successful when I enter only strings or number. But when my password contains #& or anything like that it will tell that password is incorrect. Though in my database that was the right password.
session_start();
// Change this to your connection info.
$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'root';
$DATABASE_PASS = '';
$DATABASE_NAME = 'Data-Six';
// Try and connect using the info above.
$con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
if ( mysqli_connect_errno() ) {
// If there is an error with the connection, stop the script and display the error.
die ('Failed to connect to MySQL: ' . mysqli_connect_error());
}
// Now we check if the data from the login form was submitted, isset() will check if the data exists.
if ( !isset($_POST['username'], $_POST['password']) ) {
// Could not get the data that should have been sent.
die ('Please fill both the username and password field!');
}
// Prepare our SQL, preparing the SQL statement will prevent SQL injection.
if ($stmt = $con->prepare('SELECT `used-id`, `username`, `password` FROM `user-list` WHERE `username` = ?')) {
// Bind parameters (s = string, i = int, b = blob, etc), in our case the username is a string so we use "s"
$username = $_POST['username'];
$password = $_POST['password'];
$stmt->bind_param('s', $username);
$stmt->execute();
// Store the result so we can check if the account exists in the database.
$stmt->store_result();
}
if ($stmt->num_rows > 0) {
$stmt->bind_result($username, $password, $id);
$stmt->fetch();
// Account exists, now we verify the password.
// Note: remember to use password_hash in your registration file to store the hashed passwords.
if ($_POST['password'] === $password) {
// Verification success! User has loggedin!
// Create sessions so we know the user is logged in, they basically act like cookies but remember the data on the server.
session_regenerate_id();
$_SESSION['loggedin'] = TRUE;
$_SESSION['name'] = $_POST['username'];
$_SESSION['id'] = $id;
echo 'Welcome ' . $_SESSION['name'] . '!';
} else {
echo 'Incorrect password!';
}
} else {
echo 'Incorrect username!';
}
$stmt->close();
?>
The order of variables in bind_result doesn't follow the order of field names in the SQL query.
That said, store_result/bind_result is outdated and inconvenient method which was replaced by get_result that gets you a conventional PHP array.
Here is the code you need:
$sql = 'SELECT `used-id`, `username`, `password` FROM `user-list` WHERE `username` = ?';
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $_POST['username']);
$stmt->execute();
$user = $stmt->get_result()->fetch_assoc();
// if ($_POST['password'] === $password) { come onm you MUST use a hash
if ($user && password_verify($_POST['password'], $user['password']))
{
...
}
as you can see it is much more concise and convenient
I just figured out how to used the PDO statement XD! thanks team. what i did was just rearranged the query to match the Bind-result.
if ($stmt = $con->prepare('SELECT `username`, `password`, `used-id` FROM `user-list` WHERE `username` = ?')) {
$username = $_POST['username'];
$password = $_POST['password'];
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
}
if ($stmt->num_rows > 0) {
$stmt->bind_result($username, $password, $id);
$stmt->fetch();
if ($_POST['password'] === $password) {
session_regenerate_id();
$_SESSION['loggedin'] = TRUE;
$_SESSION['name'] = $_POST['username'];
$_SESSION['id'] = $id;
echo 'Welcome ' . $_SESSION['name'] . '!';
echo 'Welcome ' . $_SESSION['id'] . '!';
} else {
echo 'Incorrect password!';
}
} else {
echo 'Incorrect username!';
}
Related
So I have a basic login form for my website. But I've been testing the website today and I discovered that if you register as 'Andy' you can log in as 'Andy' but also as 'andy'.
To fix this issue I tried selecting the username from the database and comparing it to the $_POST['username'] via ===. But with no avail so I removed that part from the code again.
This is my basic login code can anyone help?
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
session_start();
$DATABASE_HOST = 'localhost';
$DATABSE_USER = 'root';
$DATABSE_PASS = '';
$DATABSE_NAME = 'test';
$_POST['username'] = htmlspecialchars($_POST['username']);
$_POST['password'] = htmlspecialchars($_POST['password']);
$con = mysqli_connect($DATABASE_HOST, $DATABSE_USER, $DATABSE_PASS, $DATABSE_NAME);
if (mysqli_connect_errno()) {
exit('Failed to connect to database' . mysqli_connect_errno());
}
if ($stmt = $con->prepare('SELECT id, password, tokens, videos FROM accounts WHERE username = ?')) {
$stmt->bind_param('s', $_POST['username']);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows > 0) {
$stmt->bind_result($id, $password, $tokens, $videos);
$stmt->fetch();
if (password_verify($_POST['password'], $password)) {
session_regenerate_id();
$_SESSION['loggedin'] = TRUE;
$_SESSION['name'] = $_POST['username'];
$_SESSION['id'] = $id;
$_SESSION['tokens'] = $tokens;
$_SESSION['videos'] = $videos;
header('Location: home.php');
} else {
echo 'Incorrect username or password';
}
} else {
echo 'Incorrect username or password';
}
$stmt->close();
}
Based on character set and collation, non binary string comparison is case insensitive. One way is to use BINARY to compare your input with column value or use COLLATE operator to change collation in one that will result in case sensitive search.
In your case, change your query to:
SELECT id, password, tokens, videos FROM accounts WHERE BINARY username = 'Andy'
Or use COLLATE like described in MySQL docs: https://dev.mysql.com/doc/refman/8.0/en/case-sensitivity.html
This question already has an answer here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Closed 2 years ago.
Hey so I've followed a tutorial on how to create a functional registration system with php and all the code seems to work just fine, however the data I input in my registration form doesn't show up in my database even though the script gives me the output that I have successfully registered. Does anyone know a solution to this?
<?php
// Connect to the db
$DATABASE_HOST = 'localhost';
$DATABSE_USER = 'root';
$DATABSE_PASS = '';
$DATABSE_NAME = 'phplogin';
// Try to connect
$con = mysqli_connect($DATABASE_HOST, $DATABSE_USER, $DATABSE_PASS, $DATABSE_NAME);
if(mysqli_connect_errno()) {
//If there is an error stop the script and display the error
exit('Failed to connect to MySQL: '. mysqli_connect_error());
}
//check if the data already exists
if (!isset($_POST['username'], $_POST['password'], $_POST['email'])) {
//Could not get the data that should have been sent
exit('Please register first');
}
//Submitted registration values are not empty
if (empty($_POST['username']) || empty($_POST['password']) || empty($_POST['email'])) {
//if empty exit the script
exit('Please complete the register form');
}
//check if the username has been used already
if ($stmt = $con->prepare('SELECT id, password FROM accounts WHERE username = ?')) {
//encrypt password
$stmt->bind_param('s', $_POST['username']);
$stmt->execute();
$stmt->store_result();
//store the results to be able to check the db
if ($stmt->num_rows > 0) {
//username already exists
echo 'Username already used';
} else {
//Insert new account
if ($stmt = $con->prepare('INSERT INTO accounts (username, password, email) VALUES (?, ?, ?)')) {
//hash the password and use password_verify
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
$stmt->bind_param('sss', $_POST['username'], $password, $POST['email']);
$stmt->execute();
echo 'You have succesfully registered, you can now login';
}}
$stmt->close();
} else {
//Something wrong with the sql statement
echo 'Could not prepare Statement!';
}
$con->close();
?>
It is very good practise to add error checking to your code when developing. An easy way to this is to add this at the top of your php page inside php code tags to at least echo errors out on your page -
error_reporting(E_ALL);
ini_set('display_errors', 1);
Your code should look like this, should return a record. If you had error reporting on, it would have told you where the errors are -
// Connect to the db
$DATABASE_HOST = 'localhost';
$DATABSE_USER = 'root';
$DATABSE_PASS = '';
$DATABSE_NAME = 'phplogin';
// Try to connect
$con = mysqli_connect($DATABASE_HOST, $DATABSE_USER, $DATABSE_PASS, $DATABSE_NAME);
if(mysqli_connect_errno()) {
//If there is an error stop the script and display the error
exit('Failed to connect to MySQL: '. mysqli_connect_error());
}
//check if the data already exists
if (!isset($_POST['username']) || !isset(['password']) || !isset($_POST['email'])) {
//Could not get the data that should have been sent
exit('Please register first');
} else {
//check if the username has been used already
if ($stmt = $con->prepare('SELECT id, password FROM accounts WHERE username = ?')) {
//encrypt password
$stmt->bind_param('s', $_POST['username']);
$stmt->execute();
$stmt->store_result();
//username already exists
echo 'Username already used';
} else {
//Insert new account
if ($stmt = $con->prepare('INSERT INTO accounts (username, password, email) VALUES (?, ?, ?)')) {
//hash the password and use password_verify
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
$stmt->bind_param('sss', $_POST['username'], $password, $POST['email']);
$stmt->execute();
echo 'You have succesfully registered, you can now login';
} else {
echo 'Data not inserted...';
}
}
$stmt->close();
}
$con->close();
This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 4 years ago.
I am learning how to use prepared statements in my simple login system to make it more secure.
I have followed a few different tutorials to get it working but cant get it to work. When i enter the username and password wrong it gives me the error. When i enter the username and password correct i still get the error.
What am i doing wrong?
I am new to this so apologies for any obvious errors.
I have also looked into hashing my password as it is being stored as plain text in the database at the moment but that will be my next step after i get this working.
Here is my code:
<?php
error_reporting(E_ALL); ini_set('display_errors', 1);
session_start(); // Starting Session
$error=''; // Variable To Store Error Message
if($SERVER['REQUESTMETHOD'] == 'POST') {
if (empty($POST['username']) || empty($POST['password'])) {
$error = "Enter Username and Password";
}
else
{
// Define $username and $password
$username = $_POST['username'];
$password = $_POST['password'];
//connect to database
include('dbconx.php');
}
$stmt = $con->prepare("SELECT * from admin where password=? AND username=?");
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$stmt->bind_result($id, $username, $password);
$stmt->store_result();
if($stmt->num_rows == 1) //To check if the row exists
{
$_SESSION['login_user'] = $username; // Initializing Session
header("location: confirm.php"); // Redirecting To Other Page
}
else {
$error = "Username or Password is incorrect";
}
mysqli_close($con); // Closing Connection
}
?>
You have your bound parameter arguments backwards. Your query binds password then username but your bind_param() uses $username then $password.
I've never been a fan of using the number of rows returned to determine existence. Instead, you can simply use fetch(). It will return a boolean value indicating whether or not there was a result.
For example
$stmt = $con->prepare('SELECT id from admin where password = ? AND username = ?');
$stmt->bind_param('ss', $password, $username); // note the order
$stmt->execute();
$stmt->bind_result($id);
if ($stmt->fetch()) {
$_SESSION['login_user'] = $username;
$_SESSION['login_user_id'] = $id; // probably important
header("Location: confirm.php");
exit; // always exit after a "Location" header
} else {
$error = "Username or Password is incorrect";
}
mysqli_stmt::store_result should be called before mysqli_stmt::bind_result, also you would need to call mysqli_stmt::seek_data and mysqli_stmt::fetch to get the result.
Example :
<?php
$db = new Mysqli(...);
$inputUsername = $_POST['username'] ?? '';
$inputPassword = $_POST['password'] ?? '';
$statment = $db->prepare('SELECT `id`,`username`,`password` FROM `admin` WHERE `username` = ?');
$statment->bind_param('s',$inputUsername);
$statment->execute();
$statment->store_result();
$statment->bind_result($id,$username,$password);
if($statment->num_rows) {
$statment->data_seek(0);
$statment->fetch();
/**
* this is not secure
* #see http://php.net/manual/en/function.password-hash.php
*/
if($inputPassword === $password) {
echo sprintf('Welcome, %s!',$username);
} else {
echo 'Incorrect password!';
}
} else {
echo sprintf('No such user with the given username (%s)',$inputUsername);
}
$statment->close();
$db->close();
Removed bind_result and store_result for get_result and fetch_assoc. It makes getting db records more flexible and stable.
Also added exit(); after redirection so no other codes will be executed after redirect command.
Typo in:
if (empty($POST['username']) || empty($POST['password']))
^ $POST should be $_POST instead.
$error is not being checked properly if empty or not. And still goes through mysqli functions block even if there is an error. Fixed that by creating an appropriate if statement that encloses the mysqli funtions block.
Also added proper indentation to the code for readability.
New Code:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
session_start(); // Starting Session
$error=''; // Variable To Store Error Message
$_POST['username'] = isset( $_POST['username'] ) ? $_POST['username'] : '';
$_POST['password'] = isset( $_POST['password'] ) ? $_POST['password'] : '';
if($_SERVER['REQUEST_METHOD'] == 'POST') {
if (empty($_POST['username']) || empty($_POST['password'])) {
$error = "Enter Username and Password";
}
else{
// Define $username and $password
$username = $_POST['username'];
$password = $_POST['password'];
//connect to database
include('dbconx.php');
}
if( $error == "" ) {
$stmt = $con->prepare("SELECT * from students where username=? AND password=?");
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows == 1) {
$row = $result->fetch_assoc();
$_SESSION['login_user'] = $row['username']; // Initializing Session
header("location: confirm.php");exit(); // Redirecting To Other Page
}
else {
$error = "Username or Password is incorrect";
}
mysqli_close($con); // Closing Connection
}
echo $error;
}
?>
im trying to verify the users hashed password with their input but i cant get it working, so far it idenfities if theres a user with that username but it just wont verify the password. here is my code
<?php
$serverName = "localhost"; //Variables to access the user database
$username = "root";
$password = "";
$database = "snake_database";
$errors = []; //Array of all the errors to display to the user
$conn = mysqli_connect($serverName, $username, $password, $database); //Connect to the database
if(!$conn){ //If the database failed to connect
die("Database failed to connect: " .mysqli_connect_error()); //Display an error message
}
$username = $_POST['username']; //set the username/ password varaibles
$password = $_POST['password'];
$hashPass = password_hash($password, PASSWORD_DEFAULT); //Encrypt the password
$sql = "SELECT * FROM users WHERE username = ?"; //Select all usernames and passwords
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->get_result();
$count = mysqli_num_rows($result); //Count how many results there are
if ($count == 1)
{
$sql = "SELECT password FROM users WHERE username = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->get_result();
if(password_verify($password, $result )){
$count = 2;
}
}
if($count == 2) //If there is 1 account that matches
{
$stmt->close(); //Close the statment and connection
$conn->close();
session_start();
$_SESSION["LoggedUser"] = $username; //Log the user in
$_SESSION["lastPage"] = "login.php";
header("location: profile.php"); //Direct the user to their profile
}else //if there is no accounts that match
{
array_push($errors, "Username or password is incorrect");
session_start();
$_SESSION["loginErrors"] = $errors;
$_SESSION["lastPage"] = "login.php"; //Make this page the last page
header("location: index.php"); //Go to the homepage
}
?>
any help is appriciated, thanks
You are doing a lot of things you dont need to do.
A SELECT * will return all the columns so you dont need to do another SELECT for just the password.
Also you should not password_hash() the password again, when checking a password against the one already stored on the database. Use password_verify() and that will do all the checking. So you pass it the hashed_password from the database and the plain text password the user just entered on the screen, it will return true or false telling you if the password entered matched the hashed one on the database
<?php
// always do this early in the code
session_start();
$serverName = "localhost";
$username = "root";
$password = "";
$database = "snake_database";
$errors = []; //Array of all the errors to display to the user
$conn = mysqli_connect($serverName, $username, $password, $database);
if(!$conn){
die("Database failed to connect: " .mysqli_connect_error());
}
// dont hash password again
//$hashPass = password_hash($password, PASSWORD_DEFAULT);
$sql = "SELECT * FROM users WHERE username = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $_POST['username']);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows == 1) {
$row = $result->fetch_assoc();
if(password_verify($_POST['password'], $row['password'] )){
// ----------------^^^^^^^^^^^^^^^^^^--^^^^^^^^^^^^^^^^
// Plain text pwd hashed pwd from db
$_SESSION["LoggedUser"] = $_POST['username'];
$_SESSION["lastPage"] = "login.php";
header("location: profile.php");
// put exit after a redirect as header() does not stop execution
exit;
}
} else {
$errors[] = "Username or password is incorrect";
$_SESSION["loginErrors"] = $errors;
$_SESSION["lastPage"] = "login.php";
header("location: index.php");
exit;
}
?>
I want to show data from database to only currently logged user. So for example, if I want to show him when did he created his account, how can I show him only this value? And I mean this value of only his account. Not all.
I tried
<?php
$dbhost = '';
$dbuser = '';
$dbpass = '';
$conn = mysql_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('Could not connect: ' . mysql_error());
}
$sql = "Select date from members"
mysql_select_db('');
$retval = mysql_query( $sql, $conn );
if(! $retval )
{
die('Could not get data: ' . mysql_error());
}
while($row = mysql_fetch_array($retval, MYSQL_ASSOC))
{
echo "{$row['date']} <p> ";
}
?>
But this shows ALL dates from that table. I want to show date of currently logged user only.
Thanks
EDIT :
Users log in with email and pass (which is hashed)
Here is my function for login
function login($email, $password, $mysqli) {
// Using prepared statements means that SQL injection is not possible.
if ($stmt = $mysqli->prepare("SELECT id, username, password, salt
FROM members
WHERE email = ?
LIMIT 1")) {
$stmt->bind_param('s', $email); // Bind "$email" to parameter.
$stmt->execute(); // Execute the prepared query.
$stmt->store_result();
// get variables from result.
$stmt->bind_result($user_id, $username, $db_password, $salt);
$stmt->fetch();
// hash the password with the unique salt.
$password = hash('sha512', $password . $salt);
if ($stmt->num_rows == 1) {
// If the user exists we check if the account is locked
// from too many login attempts
if (checkbrute($user_id, $mysqli) == true) {
// Account is locked
// Send an email to user saying their account is locked
return false;
} else {
// Check if the password in the database matches
// the password the user submitted.
if ($db_password == $password) {
// Password is correct!
// Get the user-agent string of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT'];
// XSS protection as we might print this value
$user_id = preg_replace("/[^0-9]+/", "", $user_id);
$_SESSION['user_id'] = $user_id;
// XSS protection as we might print this value
$username = preg_replace("/[^a-zA-Z0-9_\-]+/",
"",
$username);
$_SESSION['username'] = $username;
$_SESSION['email'] = $email;
$_SESSION['login_string'] = hash('sha512',
$password . $user_browser);
// Login successful.
return true;
} else {
// Password is not correct
// We record this attempt in the database
$now = time();
$mysqli->query("INSERT INTO login_attempts(user_id, time)
VALUES ('$user_id', '$now')");
return false;
}
}
} else {
// No user exists.
return false;
}
}
}
Use a the WHERE column='value' code at the end of your SQL (see: http://www.tizag.com/mysqlTutorial/mysqlwhere.php)
Example:
If you know the user's ID that is used in your database, store that in a variable (here called $usersIDnr).
Then use the columns name (userID for example) to use in the following code at the end of your SQL:
WHERE userID='$usersIDnr'