mysqli_fetch_array($result, MYSQLI_NUM); - php

This mysqli_fetch_array not returning values. Checked it for SQL errors, none found. some error in PHP or functions I guess. Please help me correct it.
$login = login($username, $password);
if ($login == false) {
$errors[] = "That username and password combination is incorrect";
}
// validate login
function login($username, $password){
$user_id = id_from_username($username);
echo $user_id;
$password = md5($password);
$username = sanitize($username);
$query = "SELECT `password` FROM `user_data` WHERE `username` = '$username' ";
$result = mysqli_query($conn,$query);
$row = mysqli_fetch_array($result, MYSQLI_NUM);
if ($row[0] == $password) {
echo "Login successful";
return $user_id;
}
else{
echo "Login not successful";
return false;
}
}
// user id from username
function id_from_username($username){
$username = sanitize($username);
$query = "SELECT `user_id` FROM `user_data` WHERE `username` = '$username'";
$result = mysqli_query($conn,$query);
$row = mysqli_fetch_array($result, MYSQLI_NUM);
return $row[0];
}

EDIT: As Lawrence correctly pointed out I missed the variable scope issue. mysqli_query does not have access to $conn variable.
Try to check the number of returned rows in the $result:
echo $result->num_rows;
Or print it to the log if you have some. Not sure how you are checking mysqli_fetch_array does not return values - try var_dump() or print_r().
Few further recommendations:
Both queries in your question select from the same table - user_data - it is pretty inefficient to do it separately (unless id_from_username is commonly used elsewhere), I'd merge that into one query to select it at once:
SELECT user_id, password FROM user_data WHERE ...
Using mysqli_query and concatenating user input into the query is usually a bad idea. Not sure what your sanitize function does but I'd still use variable binding instead, even mysqli supports that with mysqli_prepare, see here.
Based on your code you are storing passwords in database using md5. This is a very bad practice. PHP provides very nice functions password_hash and password_verify since PHP 5.5.0, they will handle password hashing for you and make your application a lot more secure.

Related

Why is this login and registration system not checking the password correctly?

Basically I am having issues with hashing and getting the password verified, and I was hoping someone could help me out by proof reading some of the code.
Below is the registration (php code):
include '../includes/connection.php';
$userID = $_POST['userID'];
$userName = $_POST['userName'];
$Pass = $_POST['password'];
$encrypted_password = password_hash($Pass, PASSWORD_DEFAULT);
if(!empty($userName) && !empty($Pass) && !empty($userID)){
$records = "SELECT * FROM Admins WHERE ID='$userID' OR Username='$userName' OR Password='$encrypted_password'";
$results = mysqli_query($connect,$records);
if ($results->num_rows == 1){
$message = "You have already requested an account.";
echo "<script type='text/javascript'>alert('$message');</script>";
}else{
$query = "INSERT INTO Admins (`ID`,`Username`,`Password`,`AdminLevel`) VALUES ('$userID','$userName','$encrypted_password','0')";
$run = mysqli_query($connect,$query);
$message = "Your request has been submitted.";
echo "<script type='text/javascript'>alert('$message');</script>";
}
}
Below is the login (php code)
if(!empty($userName) && !empty($Pass)){
$sql = "SELECT * FROM Admins WHERE Username='$userName'";
$sqlr = mysqli_query($connect,$sql);
$sqlrow = $sqlr->fetch_assoc();
$dbPass = $sqlrow['Password'];
$hash = password_verify($Pass, $dbPass);
if ($hash == 0){
die("There was no password found matching what you have entered.");
}else{
$records = "SELECT * FROM Admins WHERE Username='$userName' AND Password='$hash'";
$results = mysqli_query($connect,$records);
if ($results->num_rows == 1){
$row = $results->fetch_assoc();
$_SESSION['user_id'] = $row['ID'];
$_SESSION['admin_level'] = $row['AdminLevel'];
$_SESSION['user_name'] = $row['Username'];
$easyName = $_SESSION['user_name'];
$recordsS = "UPDATE `Admins` SET Status='1' WHERE Username='$userName'";
$resultsS = mysqli_query($connect,$recordsS);
header("Location: index.php");
}else{
die("Sorry... you have entered incorrect login information.");
}
}
}
This is the database heading: https://gyazo.com/69380c5cd0df0259d31799b71f33ce47
When I test this on the website and I login with correct information, "Sorry... you have entered incorrect login information." is echoed.
If I login with false information, "There was no password found matching what you have entered." is echoed.
Why can it detect the password, but not properly execute the else statement in the login section?
Your $records query is failing because you are selecting Password='$hash'" where $hash is either true, or false. The query should have this condition: Password='$dbPass'"
Just as a gut check: The important thing to note is the password field in the database should be huge. The password_hash() can generate some very lengthy text (the current default is 60 characters), so making the field larger will allow for the length needed. Secondly the PHP team is adding more algorithms to the method which means the hash can and will grow. We also do not want to limit our user's ability to use the password or passphrase of their choice. It's best to leave room for the changes.
One more thing: Little Bobby says your script is at risk for SQL Injection Attacks. Learn about prepared statements for MySQLi. Even escaping the string is not safe! Don't believe it?
You have a small mistake in the Query:
$records = "SELECT * FROM Admins WHERE Username='$userName' AND Password='$hash'";
You are matching password against a boolean by mistake. It should be:
$records = "SELECT * FROM Admins WHERE Username='$userName' AND Password='$dbPass'";
You need to hash the $Pass variable for this match. The function password_verify returns a boolean after making the match but the actual hash is done inside the method.

PHP MYSQLi query only accesses user on first row

Follow the links above, in sequence, for an example of a username & password login web based system, developed using PHP, JavaScript and a MySQL database.
Follow the links above, in sequence, for an example of a username & password login web based system, developed using PHP, JavaScript and a MySQL database.
Follow the links above, in sequence, for an example of a username & password login web based system, developed using PHP, JavaScript and a MySQL database.
You are testing only the first row of the table user. When you test using the if statement, the first row returned is either the user trying to log in, or not.
Instead, you can do the following:
function user_exists($username) {
$username = sanitize($username);
$query = mysqli_query($_POST['x'], "SELECT * FROM users where username ='".$username."'");
$row = mysqli_fetch_array($query);
if(count($row)>0) {
return true;
}
else return false;
}
This looks for all rows with the given username. Of course, testing passwords or other things will depend on actually iterating through the array fetched, instead of just checking the count.
I finally did it yesterday thanks to you guys. It works well however is needed to be repeated in other functions involved (which is what failed) and yes I forgot my error reporting was turned off, making life harder for myself:
function user_exists($username) {
$username = sanitize($username);
$query = mysqli_query($_POST['x'], "SELECT `username` FROM `users` WHERE `username` = '$username'");
while($row = mysqli_fetch_assoc($query)){
$rows[] = $row;
}
if (count($rows) > 0) {
return true;} else return false;
}
Same done for the login function:
function login($username, $password){
$username = sanitize($username);
$password = md5($password);
$query = mysqli_query($_POST['x'], "SELECT `userid` FROM `users` WHERE `username` = '$username' AND `password` = '$password'");
while($row = mysqli_fetch_array($query)){
$rows[] = $row;
}
if(count($rows) > 0) {
$userid = user_id_from_username($username);
return $userid; } else return false;
Thanks again!

Mysql query IFEXIST does not return any result

I am trying to create a login form in PHP. i am passing the username and password that user had entered and check weather that exist in the data base.
i have done the coding, but IF EXIST query does not return any result.
can any one help me to fix this. or give me a alternate idea.. Thank you...
<?php
$name= $_POST["usname"];
$pass = $_POST ["password"];
$connection = mysqli_connect("localhost","sathya","sathya","learning1");
//mysqli_query($connection,"INSERT INTO user (name, password) VALUES ('".$name."', '".$pass."')");
$result = mysqli_query($connection, "IF EXISTS(SELECT * FROM user WHERE name='".$name."'AND password='".$pass."')");
mysqli_close($connection);
echo "result ".$result;
if($result == True){
header("Location: logedin.php");
//redirect_to('logedin.php');
}else{
echo "not logged in installed";
}
?>
This is a late answer, but there are a few things you need to be made aware of. (Not taking away from the accepted answer).
You will need to use if(mysqli_num_rows($result) > 0) because your query will always be TRUE if the username matches and the password does NOT, and vice-versa.
You are better off using mysqli_num_rows() rather than using if($result == True)
Sidenote: Consult my footnotes regarding password storage and SQL injection.
<?php
$DB_HOST = "xxx";
$DB_NAME = "xxx";
$DB_PASS = "xxx";
$DB_USER = "xxx";
$db = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME);
if($db->connect_errno > 0) {
die('Connection failed [' . $db->connect_error . ']');
}
$name = $_POST["usname"]; // See footnotes about this
$pass = $_POST ["password"]; // See footnotes about this
$result = mysqli_query($db, "SELECT EXISTS(SELECT * FROM users WHERE username='".$name."' AND password='".$pass."')");
// Works just as well
// $result = mysqli_query($db, "SELECT * FROM users WHERE username='".$name."' AND password='".$pass."'");
if(mysqli_num_rows($result) > 0){
echo "Both match.";
}
else{
echo "Sorry, there was not a perfect match.";
}
Footnotes:
You can also use:
$result = mysqli_query($db, "SELECT * FROM users WHERE username='".$name."' AND password='".$pass."'");
Which does the same for SELECT EXISTS(SELECT * while using less characters.
or choose actual columns:
$result = mysqli_query($db, "SELECT username, password FROM users WHERE username='".$name."' AND password='".$pass."'");
I suggest that you use prepared statements and sanitize your inputs. Not doing so will leave you open to SQL injection.
Here are a few tutorials on (mysqli) prepared statements that you can study and try:
Tutorial one
Tutorial two
Tutorial three
Here are a few tutorials on PDO:
PDO tutorial one
PDO tutorial two
PDO tutorial three
Passwords
I also noticed that you are storing passwords in plain text. This is not recommended.
Use one of the following:
CRYPT_BLOWFISH
crypt()
bcrypt()
scrypt()
On OPENWALL
PBKDF2
PBKDF2 on PHP.net
PHP 5.5's password_hash() function.
Compatibility pack (if PHP < 5.5) https://github.com/ircmaxell/password_compat/
Other links:
PBKDF2 For PHP
I can't say anything about the PHP part, but the query will surely result in a syntax error.
IF whatever ... is only allowed in stored procedures or functions, not in single queries. You can however replace the IF with SELECT like
$result = mysqli_query($connection, "SELECT EXISTS(SELECT * FROM user WHERE name='".$name."'AND password='".$pass."')");
This query would return either 0 (if no entry exists) or 1 (if an entry exists). It's also a good idea to use EXISTS as it stops the query as soon as an entry was found and does not return the whole dataset.
You can try this beside using 'IF EXISTS' function--
$result = mysqli_query($connection, "SELECT * FROM user WHERE name='".$name."'AND password='".$pass."'");
$count=mysql_num_rows($result);
if($count==1) // $count=1 if any row is present with mathing username and pwd in db
{
echo "user already logged in";
}
else
{
echo "user not exist";
}

PDO and checking if username or email is taken

I am converting to PDO and I'm having a problem converting at the section where it checks to see if the username and email is taken or not.
below is the code:
<?php
session_start();
$host = "localhost";
$username = "root";
$password = "123";
$dbname = "test";
$conn = new PDO("mysql:host=$host;dbname=$dbname",$username,$password);
?>
<?php
if(isset($_POST['register'])){
$username = $_POST['username'];
$password = $_POST['password'];
$email = $_POST['email'];
$usernamecheck = $conn->query("SELECT `id` FROM `user` WHERE username='$username'");
$emailcheck = $conn->query("SELECT `id` FROM `user` WHERE email='$email'");
if(mysql_num_rows($usernamecheck) > 0){
echo "That username is already taken";
}elseif(mysql_num_rows($emailcheck) > 0){
echo "That e-mail address is already in use";
}
?>
The errors I get are at the two following lines:
if(mysql_num_rows($usernamecheck) > 0){
}elseif(mysql_num_rows($emailcheck) > 0){
Thanks in Advance.
You're using mysql_num_rows() for a PDO query. You can't mix these APIs.
You're also interpolating $_POST variables directly into your SQL, which is a no-no for security. The benefit of using PDO is that you can easily use SQL query parameters instead, which is much easier and more secure.
Here's how I'd code this task:
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare("SELECT COUNT(*) AS count FROM `user` WHERE username=?");
$stmt->execute(array($username));
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$username_count = $row["count"];
}
if ($username_count > 0) {
echo "That username is already taken";
}
$stmt = $conn->prepare("SELECT COUNT(*) AS count FROM `user` WHERE email=?");
$stmt->execute(array($email));
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$email_count = $row["count"];
}
if ($email_count > 0) {
echo "That email address is already in use";
}
Also keep in mind that even if you check first, you should assume that someday two people may be trying to create the same username simultaneously, and if the code for their respective requests executes in just the wrong sequence, they could both be told the username does not exist, go ahead and INSERT it. So you should define a UNIQUE KEY on the columns that must be unique. Only the first one to INSERT will succeed, the other will get an error. So you must check for errors.
First of all, the entire task is rather pointless. Making a username unique makes no sense. Given email is used to identify a user, the username - or, rather - display name could be anything and allow duplicates, just like it is done right here, on Stack Overflow.
But if you want the username to be unique, obviously it can be done in one query, without any num rows functionality which being essentially useless
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT username, email AS count FROM `user` WHERE username=? OR email=?";
$stmt = $conn->prepare($sql);
$stmt->execute([$username, $email]);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
if ($row['username'] === $username) {
$errors[] = "Username is taken";
}
if ($row['email'] === $email) {
$errors[] = "Email is taken";
}
}

user login with php and mysql database

I'm new to mysql and php.
Been working on creating a database with a table for users.
I've managed to successfully add users to the database, and their passwords with md5(yea i know it's not secure), it's not going to be launched online.
My problem is, how do I log a user in, based on their correct username and password.
here is my code
My logic is taht after the query runs, it will return either true or false.
If true, then display successful login, else unsuccessful.
however, even if i input a correct username and password, i still get a unsuccessful login message
i checked the mysql database, and the uesrname is in there correctly
ideas?
if(!empty($_POST['userLog']) && !empty($_POST['passLog']))
{
//set the username and password variables from the form
$username = $_POST['userLog'];
$password = $_POST['passLog'];
//create sql string to retrieve the string from the database table "users"
$sql = "SELECT * FROM `users` WHERE userName = '$username' AND password = md5('$password')";
$result = mysql_query($sql);
if ($result == true) {
$return = "<font color=#008000><Center><b>**Successful Login**</b></Center></font>";
} else {
$return = "<font color=#ff0000><Center><b>**Failed Login**</b></Center></font>";
}
print($return);
}
I'm not entirely sure your SQL will run, but just to be on the safe side.
Change it so that
$password_hash = md5($password);
$sql = "SELECT * FROM `users` WHERE userName = '$username' AND password = '$password_hash'";
And for your original question
if(mysql_num_rows($result) == 1) { //If the SQL returns one row, that means that a user was found with `userName = $username` and `password = md5($password)`
// Login
} else {
// Authentication Failed
}
Also, consider using MySQLi instead of MySQL since it has been depreciated.
First of all, protect your code against SQL injections.
Then, make sure that the password in the DB is really hashed with md5() function.
Make sure you form uses POST method to pass the data to the script.
Try the following code:
if(!empty($_POST['userLog']) && !empty($_POST['passLog']))
{
//set the username and password variables from the form
$username = $_POST['userLog'];
$password = $_POST['passLog'];
//create sql string to retrieve the string from the database table "users"
$sql = "SELECT * FROM `users` WHERE userName = '". addslashes($username) ."' AND password = '". md5('$password')."'";
$result = mysql_query($sql);
if (mysql_num_rows($result)>0) {
$return = "<font color=#008000><Center><b>**Successful Login**</b></Center></font>";
} else {
$return = "<font color=#ff0000><Center><b>**Failed Login**</b></Center></font>";
}
print($return);
}
mysql_query doesn't return TRUE or FALSE. Per the docs (http://php.net/manual/en/function.mysql-query.php), it returns a resource if successful, or FALSE if there is an error. You need to evaluate the resource to see if it's valid.
if(!empty($_POST['userLog']) && !empty($_POST['passLog']))
{
//set the username and password variables from the form
$username = $_POST['userLog'];
$password = $_POST['passLog'];
//create sql string to retrieve the string from the database table "users"
$sql = "SELECT * FROM `users` WHERE userName = '$username' AND password = md5('$password')";
$result = mysql_query($sql);
if ($result && $row = mysql_fetch_assoc($result)) {
$return = "<font color=#008000><Center><b>**Successful Login**</b></Center></font>";
} else {
$return = "<font color=#ff0000><Center><b>**Failed Login**</b></Center></font>";
}
print($return);
}
As mentioned in my comment, the issue seems to be your sql string. Instead of hashing, you are putting the method into the string. So change
$sql = "SELECT * FROM `users` WHERE userName = '$username' AND password = md5('$password')";
to
$sql = "SELECT * FROM `users` WHERE userName ='$username' AND password = '".md5('$password')."'";
Your result will not be true or false, but since php treats any value not a 0 as true, it will work as is.
Also, it is strongly recommended to escape all data going into your sql string to prevent sql injection. Another note: mysql is being deprecated, so now would be a great time to move to something like mysqli.

Categories