Why wont this check to see if a user exists? - php

I'm performing a query to check if a user exists before adding it to the database. If that result comes back then die and echo 'username already exists' but if it comes back empty then add the new user to the database.
For some reason it just adds a new user to the database anyway.
//If post was
if (isset($_POST['submit'])) {
// Check if username is blank
if (!isset($_POST['username']) || empty($_POST['username'])) {
echo "Username was blank<br />";
die();
} else {
$username = mysqli_real_escape_string($connection, $_POST['username']);
}
// Check if password is blank
if (!isset($_POST['password']) || empty($_POST['password'])) {
echo "Password was blank<br />";
die();
} else {
$password = mysqli_real_escape_string($connection, $_POST['password']);
$password2 = md5($password);
//echo $password;
}
// Check if email is blank
if (!isset($_POST['email']) || empty($_POST['email'])) {
echo "Email was blank<br />";
die();
} else {
$email = mysqli_real_escape_string($connection, $_POST['email']);
//$password = md5($password);
//echo $password;
}
//Check to see if username alread exsists
$query_check = "SELECT * FROM users WHERE user = '$username' LIMIT 1";
$result_check = mysqli_query($connection, $query_check);
if(count(mysqli_fetch_array($result_check)) === 1) {
echo "Username exists.";
die();
} else {
$query = "INSERT INTO users (user, pass, email) VALUES ('$username','$password2','$email');";
$result = mysqli_query($connection, $query);
if($result){ // returned TRUE, e.g. in case of a DELETE sql
$_SESSION["username"] = $username;
header("Location: ../profile.php");
} else { // returned FALSE
//echo "Error: " . mysqli_error($connection);
echo "Error during register <a href='../register.php'>Back To Register</a>";
die();
}
}
} else {
header("Location: ../index.php");
}

After taking a few minutes testing your code, found that you're using the wrong function.
mysqli_fetch_array():
Fetch a result row as an associative, a numeric array, or both
You're trying to fetch an associative array.
As opposed to mysqli_num_rows():
Gets the number of rows in a result
Replace (and which seems to have been taken from FĂ©lix's answer)
if(count(mysqli_fetch_array($result_check)) === 1)
with
if(mysqli_num_rows($result_check) == 1)
or
if(mysqli_num_rows($result_check) > 0)
Your original post contained:
if(mysqli_fetch_array($result_check) === 1)
which still stands to be the wrong method.
I even said to use mysqli_num_rows() in a comment, but nothing was said about it:
if(mysqli_num_rows($result_check) >0) and make sure $username is defined. We don't know how/where if it is even defined.
Now, if THAT fails, then your form element isn't named, and/or something else in your form is failing you.
I.e.: <input type="text" name="username">
Add error reporting to the top of your file(s) which will help find errors.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// rest of your code
Sidenote: Error reporting should only be done in staging, and never production.
Regarding using MD5.
That isn't considered safe to use anymore, as far as password hashing goes.
That technology is old and is considered broken.
For password storage, use CRYPT_BLOWFISH or PHP 5.5's password_hash() function.
For PHP < 5.5 use the password_hash() compatibility pack.
Pulled from ircmaxell's answer which uses PDO with prepared statements and password_hash():
Just use a library. Seriously. They exist for a reason.
PHP 5.5+: use password_hash()
PHP 5.3.7+: use password-compat (a compatibility pack for above
All others: use phpass
Don't do it yourself. If you're creating your own salt, YOU'RE DOING IT WRONG. You should be using a library that handles that for you.
$dbh = new PDO(...);
$username = $_POST["username"];
$email = $_POST["email"];
$password = $_POST["password"];
$hash = password_hash($password, PASSWORD_DEFAULT);
$stmt = $dbh->prepare("insert into users set username=?, email=?, password=?");
$stmt->execute([$username, $email, $hash]);
And on login:
$sql = "SELECT * FROM users WHERE username = ?";
$stmt = $dbh->prepare($sql);
$result = $stmt->execute([$_POST['username']]);
$users = $result->fetchAll();
if (isset($users[0]) {
if (password_verify($_POST['password'], $users[0]->password) {
// valid login
} else {
// invalid password
}
} else {
// invalid username
}
Footnotes:
I noticed you are using headers.
You should add exit; after each header. Otherwise, your code may want to continue executing.
header("Location: ../profile.php");
exit;
and do the same for the other one also.
You're also using sessions. session_start(); isn't present in your posted and will fail if it isn't included; an insight.

here
if(mysqli_fetch_array($result_check) === 1) {
the value returned by mysqli_fetch_array won't be an integer but an array. You seem to want to count it:
if(count(mysqli_fetch_array($result_check)) === 1) {
In the case somehow two users would have been inserted for whatever reason, checking if count is greater than 0 may prevent a third one being inserted:
if(count(mysqli_fetch_array($result_check)) > 0) {

Related

the include is not including an html file

i'm making a login system linked with a database, i want to show an html file after the data get checked from the database.so, i used (the include method) an it shows me the html file in the console not on web page.
i've tried to use (require method) and tried to change it to php file and still doing the same.
<?php
$dbsevername = "127.0.0.1";
$dbusername = "root";
$dbpassword = "**************";
$dbname = "loginsystem";
$dbport = '3306';
$username = $_POST['username'];
$password = $_POST['password'];
$_SESSION["favcolor"] = "green";
$conn = mysqli_connect($dbsevername, $dbusername, $dbpassword,$dbname);
$sql = "SELECT * FROM passwords where username='$username' and password='$password';";
$result = mysqli_query($conn, $sql);
$resultCheck = mysqli_num_rows($result); // = 2
if ($resultCheck > 0) {
while($row = mysqli_fetch_assoc($result)){
if ($row['username'] == $username && $row['password'] == $password) {
include("true.html");
}
}
}else {
include("false.html");
}
mysqli_close($conn);
?>
i want to open the (true.php) or (false.php) when the data get checked.
I would rename to HTML files to PHP.
Is this actually your code? Just checking because if the files are a remote URL this makes a difference.
You are using a while loop to include a HTML file that will only ever have 1 result. There are better methods of doing this but regardless this should work and isn't the issue here. Any errors?
Try
include './true.php';
instead of
include ("true.html");
i want to open the (true.php) or (false.php) when the data get checked.
I think you are making a common rookie oversight here, because at the moment you only check if the data is correct and don't handle anything else:
I've commented through your code below to demonstrate what I mean
//if there is at least 1 result then check the data otherwise include false
if ($resultCheck > 0) {
//while we go through the results check each one
while($row = mysqli_fetch_assoc($result)){
//if the username and password match include true.html
//however you don't break out of the loop, you keep checking
//if you have decided to include true you should use break;
if ($row['username'] == $username && $row['password'] == $password) {
include("true.html");
}
//otherwise do what? this should say else include false and then should probably break out the loop here as the
//this will not fall through into the else block below as that is based on the parent condition
//so you will never include a false in this loop - only if there were 0 rows to begin with
//this means that eventually, whenever our loop finishes we will skip
//down to the next executionable line which is marked with !!!
}
}else {
include("false.html");
}
//!!!
there are some other glaring problems with your code, such as you seem to be storing passwords in pain text in your database, these should be hashed and verified, so you should never be able to just see if a password row == an input, i suggest googling php functions password_hash and password_verify
You also shouldn't be using a while loop, within your login system you must have a unique username and password combination so you should only ever return 1 row - if you have more than 1 row how can you confirm who they are? So you should be using whatever the mysqli equivalent of pdo->fetch() is (i don't know offhand because i only use pdo)
which brings me on to the fact that you should be using prepared statements to combat sql injection, at the moment this login system could be easily used to give someone full access to all your usernames and passwords, which are all stored in plain text.
$uid = $_POST['uid'];
$pwd = $_POST['pwd'];
if ($uid == null){
header("Location: ../index.php?message=ERROR 001 - Username or Password can not be
blank!");
exit();
}
if ($pwd == null){
header("Location: ../index.php?message=ERROR 001 - Username or Password can not
be blank!");
exit();
}
if ($stmt = $link->prepare("SELECT password FROM users WHERE username=?")) {
$stmt->bind_param("s", $uid);
$stmt->execute();
$stmt->bind_result($pass);
$stmt->fetch();
$stmt->close();
}
if (!$stmt) {
header("Location: ../index.php?message=ERROR 003 - Connection to the database could
not be established!");
exit();
}
$hash_pwd = $pass;
if ($hash_pwd == crypt($pwd, $hash_pwd)){
$decrypt = 1;
}else{
$decrypt = 0;
}
if ($decrypt == 0){
include ("false.html");
exit();
} else {
$stmt = $link->prepare("SELECT id FROM users WHERE username='$uid' AND password=?");
$stmt->bind_param("s", $hash_pwd);
$stmt->execute();
$stmt->bind_result($id);
$stmt->fetch();
$stmt->close();
$_SESSION['id'] = $id;
include ("true.html");
}
This should work better. You'll have to change your database relevant details. I've given you a start with storing a session variable of ID.

Using Use prepared statements and parameterized queries in PHP and MySQLi [duplicate]

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;
}
?>

Check for duplicate user from MySQL database [duplicate]

This question already has answers here:
How to check if a row exists in MySQL? (i.e. check if username or email exists in MySQL)
(4 answers)
Closed 5 years ago.
I would like to check for duplicates in a MySQL database when registering an user.
If the user exists display an error to that effect, else sign up.
I know there's a few questions like this but I found it hard to paste any of them into my code.
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
//two passwords are the same
if($_POST['password'] == $_POST['confirmedpassword']) {
$username = $mysqli->real_escape_string($_POST['username']);
$password = md5($_POST['password']);
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
$sql = "INSERT INTO members(username, password)"
. "VALUES ('$username','$password')";
//if query is successful redirect to login.php
if ($mysqli->query($sql) === true)
$_SESSION['message'] = 'Success';
header("location: login.php");
} else {
$_SESSION['message'] = "User couldnt be added";
}
} else {
$_SESSION['message'] = "Passwords dont match";
}
}
I added some salt to your md5 password to make it seem more secure, but actually this solution is not secure either. To encrypt passwords in PHP it is advisable to use the password_hash() function like this:
$pass = password_hash($password, PASSWORD_BCRYPT);
password_hash() creates a new password hash using a strong one-way hashing algorithm.
and later test it with password_verify():
password_verify ( $passToTest , $knownPasswordHash );
more the functions here: http://php.net/password-hash, http://php.net/password-verify.
Also, since you are using MySQLi consider using prepared statements, or at least properly filter your input data before applying it to the database.
More on prepared statements: http://php.net/prepared-statements.
I added a select statement to check if the user already exists in the table prior to adding the user to the database.
When using header() to change page location put exit() or die() in the next line of code if you want to exit immediately and don't want other code to execute.
Here is your code with the addition of the select statement:
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
//two passwords are the same
if($_POST['password'] == $_POST['confirmedpassword'])
{
$username = $mysqli->real_escape_string($_POST['username']);
// You might consider using salt when storing passwords like this
$salt = 'aNiceDay';
$password = md5(md5($_POST['password'].$salt).$salt);
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
$sql = "SELECT `username` FROM members WHERE `username` = '".$username."'";
$result = $mysqli->query($sql);
if(mysqli_num_rows($result) > 0)
{
echo 'User exists.';
// Do something.
}
else
{
$sql = "INSERT INTO members(username, password) VALUES ('".$username."','".$password."')";
if($mysqli->query($sql) === true)
{
$_SESSION['message'] = 'Success';
header("location: login.php");
// Important to put exit() after header so other code
// doesn't get executed.
exit();
}
else
{
$_SESSION['message'] = "User couldn't be added";
echo "User couldn't be added.";
}
}
}
else
{
$_SESSION['message'] = "Passwords dont match";
}
}
?>
So you can check that the user exists or not.
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
//two passwords are the same
if($_POST['password'] == $_POST['confirmedpassword']) {
$username = $mysqli->real_escape_string($_POST['username']);
$password = md5($_POST['password']);
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
//Check user
$CheckUserIsExist = mysqli->query("SELECT uid FROM members WHERE username='$username'");
if(mysqli_num_rows($CheckUserIsExist)==0 ){
$sql = "INSERT INTO members(username, password)"
. "VALUES ('$username','$password')";
//if query is successful redirect to login.php
if($mysqli->query($sql) === true)
$_SESSION['message'] = 'Success';
header("location: login.php");
}
} else{
echo 'This username is already in use. Please use different username';
}
else{
$_SESSION['message'] = "User couldn't be added";
}
}
else{
$_SESSION['message'] = "Passwords don't match";
}

trying to verify hashed password and validate login pdo php

Hello I am trying to use pdo to return hashed passwords from database and allow users to login while their password is being protected. I have built a sign up page which hashes the password. I am now trying to dehash this. I think I am close but this has been many days stuck in the same place, I was hoping someone could help me finalise my code?
PHP Fatal error: Uncaught Error: Call to a member function fetch() on boolean in /var/www/html/login.php:54\nStack trace:\n#0 {main}\n thrown in /var/www/html/login.php on line 54, referer: http://172.16.62.211/login.php
if (isset($_POST['submit'])){
$username = $_POST['username'];
$password = $_POST['password'];
$q = $handler->prepare('SELECT * FROM users WHERE username = ?');
$query = $q->execute(array(
$username));
$_SESSION['username'] = $username;
$count = $q->rowCount();
if ($count == 1 -> fetch(PDO::FETCH_ASSOC)){
$hash_pwd = $count['password'];
$hash = password_verify($password, $hash_pwd);
if ($hash_pwd == 0) {
header("location: login.php?error=empty");
}
else {
$q = $handler->prepare('SELECT * FROM users WHERE username = ? && password = $hash_pwd');
$query = $q->execute(array(
$username,
$password));
$count = $q->rowCount();
if($count == 1){
$_SESSION['username'] = $username;
header("location: index.php");
return;
} else {
echo '<p class="error-message3">'.'<br>'.'<br>'."You have ented an incorrecct login!<br>Please try again.".'</p>';
}}}}
?>
You need to understand the usage of password_verify, it takes raw (unhashed) version of the password and the hashed version (from your database) and returns respectively true/false.
<?php
if (password_verify($raw, $hash)) {
}
?>
You don't need to compare it in your query, just retrieve the password from by the username provided (if the username is valid) and then verify.
You WONT and you CANT 'dehash' the password from your database.
The normal routine consists basically of converting the password inserted by the user to your security logic encrypt and compare with the password stored in your db (hashed too), the two values must be equal to validate.
Dehash a password is, if the hash was done correctly, in some ways kind of impossible, not to point the security flaw about your idea.
if ($count == 1 -> fetch(PDO::FETCH_ASSOC)){
$hash_pwd = $count['password'];
$hash = password_verify($password, $hash_pwd);
if ($hash === false) {
header("location: login.php?error=empty");
} else {
$_SESSION['username'] = $username;
header("location: index.php");
return;
}
} else {
echo '<p class="error-message3">'.'<br>'.'<br>'."You have ented an incorrecct login!<br>Please try again.".'</p>';
}
PS: Indent better your code and notes that some routines you are repeating the checking, in the password_verify you already checked like a said above.

Cant see what is wrong with my script, seems to work on another site PHP login script [closed]

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 8 years ago.
Improve this question
This is my attempt at a basic mysqli php login script (im only learning, so please dont be too harsh).
Can anyone see why it would be bringing up 0 rows every time and failing to login?
<?php
$con = mysqli_connect("localhost","user","pass","database");
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL, Please contact an Administrator";
}
$username = mysqli_real_escape_string($_POST['username']);
$password = mysqli_real_escape_string($_POST['password']);
$query = "SELECT * FROM users WHERE user_name='$username' AND pass_phrase='$password'";
$result = mysqli_query($con, $query);
$row_cnt = mysqli_num_rows($result);
if (!$row_cnt == 0) {
echo "Usename/Password Combination Failed";
} else {
echo "Welcome " . $_POST['username'];
}
mysqli_close($con);
?>
You need to pass DB connection to mysqli_real_escape_string() as an added parameter.
What you're presently using:
$username = mysqli_real_escape_string($_POST['username']);
$password = mysqli_real_escape_string($_POST['password']);
What you should be using:
$username = mysqli_real_escape_string($con, $_POST['username']);
$password = mysqli_real_escape_string($con, $_POST['password']);
Plus, if if (!$row_cnt == 0) doesn't work after making those changes, try a reverse approach:
I.e.:
$row_cnt = mysqli_num_rows($result);
if ($row_cnt > 0) {
echo "Welcome " . $_POST['username'];
} else {
echo "Usename/Password Combination Failed";
}
Consider adding or die(mysqli_error($con)) to mysqli_query() to signal errors in code.
Sidenote:
I noticed you may be storing passwords in plain text. If this is the case, it is highly discouraged.
I recommed you use CRYPT_BLOWFISH or PHP 5.5's password_hash() function.
For PHP < 5.5 use the password_hash() compatibility pack.
Footnotes:
Consider looking into using:
Prepared statements, or PDO with prepared statements, they're much safer.
Try removing ! or == 0 from your if condition at the bottom. Or even better:
if ($row_cnt) {
// Welcome
} else {
// Notify about authentication failure
}
Also, it's a good practice to hash your password/pass phrase.
This is very basic approach for login, assuming you have user table with id, username, and password :
<?php
if($_SERVER['REQUEST_METHOD'] == 'POST')
{
$errors = array();
if(!$_POST['username']) //check if username has been filled
{
$errors[] = 'bla bla text for empty username notice';
}
else
{
$username = mysqli_real_escape_string($conn, trim($_POST['username']));
}
if(!$_POST['password'])//check if password has been filled
{
$errors[] = 'bla bla text for empty password notice';
}
else
{
$password = mysqli_real_escape_string($conn, trim($_POST['username']));
}
if(empty($errors)) //no errors appears
{
$query = "SELECT * FROM tablename WHERE user_name = '$username' AND password = SHA1('$password')";
$result = #mysqli_query($conn, $query);
if(mysqli_num_rows($result) == 1)
{
//if one database row (record) matches the input:
// Start the session, fetch the record and insert the three values in an array
session_start();
$_SESSION = mysqli_fetch_array($result, MYSQLI_ASSOC);
header("direct to after login page");
}
else
{
// No match was made
$errors[] = 'Sorry no record match with the data you have submitted';
}
}
else
{
// If there was a problem.
echo mysqli_connect_error($conn);
}
}
You need to fix the quoting in your query. Right now you are trying to login as a user with user name $username and password $password and most likely no such combination exists. Also unless you are allowing two users to have the same username you should just query based on the username and then compare the hashed password provided with the stored hashed password.

Categories