0

Guys & My Ladies,

This LOGIN.php was working lastnight and so I don't know why not now.

The ELSE at 53 gets triggered even though I have typed the right password!

What do you think of line 16 ? ...

if($numrows >1)

I tried the following but no luck:

if($numrows)

if($numrows !=0)

if($numrows ==2)

In the past, they worked, though. What is wrong, do you reckon ?

Guys & My Ladies,

This LOGIN.php was working lastnight and so I don't know why not now.

The ELSE at 53 gets triggered even though I have typed the right password!

What do you think of line 16 ? ...

if($numrows >1)

I tried the following but no luck:

if($numrows)

if($numrows !=0)

if($numrows ==2)

In the past, they worked, though. What is wrong, do you reckon ?

[php]

<?php
session_start();
require "conn.php";
require "site_details.php";

if(isset($_POST["member_login_submit"]))
{
    if(!empty($_POST["member_login_username_or_email"]) && !empty($_POST["member_login_password"]))
    {
        $member_login_username_or_email = trim(strip_tags(strtolower(mysqli_real_escape_string($conn,$_POST["member_login_username_or_email"]))));
        $member_login_password = trim(strip_tags(mysqli_real_escape_string($conn,$_POST["member_login_password"])));
        
        $sql = "SELECT * FROM users WHERE usernames='".$member_login_username_or_email."' OR emails='".$member_login_username_or_email."' AND passwords='".$member_login_password."'";
        $result = mysqli_query($conn,$sql);
        $numrows = mysqli_num_rows($result);
        if($numrows >1)
        {        
            while ($row = mysqli_fetch_assoc($result))
            {
                $db_username = $row["usernames"];
                $db_password = $row["passwords"];
                $db_email = $row["emails"];
                                        
                if  ($member_login_username_or_email == $db_username && $member_login_password == $db_password || $member_login_username_or_email == $db_email && $member_login_password == $db_password)            
                {
                    $_SESSION["user"] = $member_login_username_or_email;           
                    if(!empty($_POST["member_login_remember"]))
                    {
                        setcookie("member_login_username_or_email", $member_login_username_or_email, time()+ (10 * 365 * 24 * 60 * 60));
                        setcookie("member_login_password", $member_login_password, time()+ (10 * 365 * 24 * 60 * 60));                        
                    }
                    else
                    {
                        if(isset($_COOKIE["member_login_username_or_email"]))
                        {    
                            setcookie("member_login_username_or_email", "", "");
                        }
                        if(isset($_COOKIE["member_login_password"]))
                        {    
                            setcookie("member_login_password", "", "");
                        }        
                    }
                    header("location:home.php");            
                }
                else
                {
                    $message = "Invalid login!";
                }    
            }
        }
        else
        {
            $message = "Something is wrong! Try again later!";
        }        
    }
    else
    {
        $message = "You must input your Username and Password!";    
    }
}    

?>
<!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">
<?php
if(isset($message))
{
    echo $message;
}
?>
<div class="form-group">
<center><label>Username/Email:</label>
<input type="text" placeholder="Enter Username or Email" name="member_login_username_or_email" value="<?php if(isset($_COOKIE["member_login_username_or_email"])) echo $_COOKIE["member_login_username_or_email"]; ?>"</center>
</div>
<div class="form-group">
<center><label>Password:</label>
<input type="password" placeholder="Enter password" name="member_login_password" value="<?php if(isset($_COOKIE["member_login_password"])) echo $_COOKIE["member_login_password"]; ?>"></center>
</div>
<div class="form-group">
<center><label>Remember Login Details:</label>
<input type="checkbox" name="member_login_remember" /></center>
</div>
<div class="form-group">
<center><input type="submit" name="member_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><a href="member_login_password_reset.php">Reset it here!</a></font></center>
<center><font color="red" size="3"><b>Not registered ?</b><br><a href="member_register.php">Register here!</a></font></center>
</form>
</div>
</body>
</html>

[/php]
3
Contributors
6
Replies
48
Views
7 Months
Discussion Span
Last Post by diafol
2

Hi,

what you get with var_dump($numrows);?

Besides, look at your query:

SELECT * FROM users WHERE usernames='abc' OR emails='abc' AND passwords='WRONG_pass';

Basically it is like writing:

SELECT TRUE OR FALSE AND FALSE;

Which evaluates to TRUE:

+---------------------------+
|   TRUE OR FALSE AND FALSE |
|---------------------------|
|                         1 |
+---------------------------+

In this case by knowing the username you can access without the correct password. It happens because in MySQL AND has an higher precedence than OR, so the expression is read by the database like:

SELECT TRUE OR (FALSE AND FALSE);

To avoid the issue do:

SELECT (TRUE OR FALSE) AND FALSE;

Which evaluates to:

+-----------------------------+
|   (TRUE OR FALSE) AND FALSE |
|-----------------------------|
|                           0 |
+-----------------------------+

As expected.

See: https://dev.mysql.com/doc/refman/5.7/en/operator-precedence.html

Edited by cereal

0

Cereal my man,

Have you seen on gmal or something you can either enter your username or email and then the password and it would log you in ? Trying to build like that so user gets a choice to either use his username or email to login. Script should log user in aslong as "either the username or email" is a match in the username or email column and the password is a match too that is relevant to the username/email row.
So, db is like this:

Username|Email|Pass

If the username is a match on row position 5 then the password should be a match on row position 5 too.
Or,
If the email is a match on row position 5 then the password should be a match on row position 5 too.

I think you understand. Pretty basic, really. Nothing complicated.
Actually, I'm very curious to see how you would code it. A sample code is most appreciated.

Edited by UI

0

Cereal my man!

I don't know what this is as still a beginner:
var_dump($numrows);

Care to show me the example how you would code it since you reckon my code is flawed ?
Other newbies can learn from your example in present & future!

3

I don't know what this is as still a beginner: var_dump($numrows);

var_dump() returns information about expressions TRUE < FALSE or variables. For example:

$stmt = TRUE === TRUE || TRUE < FALSE && TRUE === FALSE;
$str  = 'Hello';
$fp   = fopen('php://memory', 'w+');
var_dump($stmt, $str, $fp);

It will return the data type and the value:

bool(true)
string(5) "Hello"
resource(3) of type (stream)

In my previous comment, I suggested you to verify the contents of the $numrows variable, to make sure you were receiving an integer (as expected) or NULL, which would suggest an error with the query.

About the code, I understand what you want to achieve, however query to verify only if the username or the email address exists, exclude the password for now, so do:

SELECT * FROM users WHERE usernames='abc' OR emails='abc' LIMIT 1;

I'm adding LIMIT 1 here, which can be avoided if you set unique keys on usernames and emails columns.

Once you get the row, fetch the password from the result set and compare it with the one submitted in the login request.

Right now, I suppose you are saving passwords in plain text, you should use password_hash() to generate the hash to save into the database and password_verify() to verify the attemp with the hash.

Read the following tutorial by Diafol, #11 Storing and Retrieving Authentication Data, which shows exactly the same approach that I would use here:

It is developed for PDO and uses prepared statements, it can be easily changed to MySQLi, just follow this post to get a direction:

This should be enough to change the script. Bye!

0

Cereal,

These links were suggested to me:

[url=http://bobby-tables.com/]bobby-tables.com: A guide to preventing SQL injection[/url]
[url=http://php.net/manual/en/book.filter.php]PHP: Filter - Manual[/url]
[url=http://php.net/manual/en/class.mysqli-stmt.php]PHP: mysqli_stmt - Manual[/url]
[url=http://php.net/manual/en/function.password-hash.php]PHP: password_hash - Manual[/url]
[url=http://php.net/manual/en/function.password-verify.php]PHP: password_verify - Manual[/url]
[url]https://dev.mysql.com/doc/refman/5.7/en/operator-precedence.html[/url]
[url]http://php.net/manual/en/language.operators.comparison.php[/url]
[url]http://php.net/manual/en/pdo.prepared-statements.php[/url]
[url]http://php.net/manual/en/mysqli.prepare.php[/url]
[url]http://stackoverflow.com/questions/129677/whats-the-best-method-for-sanitizing-user-input-with-php[/url]

One programmer said that this code of mine is incorrect unless I want to allow the user to login without entering a password.

$sql = "SELECT * FROM users WHERE usernames='".$member_login_username_or_email."' OR emails='".$member_login_username_or_email."' AND passwords='".$member_login_password."'";

He said to code it like this (note the brackets he added):

$sql = "SELECT * FROM users WHERE (usernames='".$member_login_username."' OR emails='".$member_login_email."') AND passwords='".$member_login_password."'";

He warned me though to use password hashing. Will look into that. Others told me to quit the md5 as it's rubbish and look into the hashing too.

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.