This code works on my computer, but when I run it on my web host's server, it doesn't. The output is "Incorrect password or email", even though I'm using the correct password. I thought I had made a mistake with the passwords, but the code won't output $r['email'] or $r['passwordHash'], at the top of the while loop. If I use mysql_result on $sql, I get the data out, so something weird must be happening with mysql_fetch_array. Am I missing something here, or is this more likely a unique problem I should address with my host's support staff?
$query = "SELECT * FROM users WHERE user='$email'";
$sql = mysql_query($query);
while($r = mysql_fetch_array($sql)) {
echo $r['email'];
echo $r['passwordhash'];
if($passwordHash == $r['passwordhash']) {
$_SESSION['user_id'] = $email;
echo "started session";
}
else {
echo "Incorrect password or email";
}
}
Use $sql = mysql_query($query) or die (mysql_error()) to check if there's something going wrong with the query.
Alternatively, you could try mysql_fetch_assoc (since I see you're most using associative arrays), to rule out a possible 'bug' of mysql_fetch_array (I doubt that but you could give it a try).
And check that $email is not empty. If it's passed through a sanitizing function (as it should have before being put into the query), see if that function have actually returned a value or just NULL or an empty string.
And, btw, why are you using a while loop? Are you supposed to get more than one record (and passwords) with the same e-mail address?
One thing to check real quick would be PHP and MySQL version on your computer versus the web server. How are you handling the hashes, because that could also cause an issue.
Are you doing something like the following?
$password = md5($password);
If so, are you converting correctly on the web server side?
$password = $_POST['password'];
$passwordHash = md5($password);
unset($password);
$query = "SELECT * FROM users WHERE user='$email'";
$sql = mysql_query($query);
while($r = mysql_fetch_array($sql)) {
echo $r['email'];
echo $r['passwordhash'];
if($passwordHash == $r['passwordhash']) {
$_SESSION['user_id'] = $email;
echo "started session";
}
else {
echo "Incorrect password or email";
}
}
Related
I am testing a login code and i ran into a problem where the information collected from a MySQL database can not be found even though the information exists inside the table, the code below says that there is 0 rows with the information i am trying to pull out, therefore it fails to execute it's primary function and always ends up executing the else solution
I have been googling around and tried different combinations and ways the code can be written as it is '".$username."' instead of '$username' but nothing seems to be working except in case where equal it to zero but that way it looses it's purpose and executes the primary function no matter what
<?php
$mysqli = new mysqli('localhost','root','password','accounts');
if (isset($_POST['login'])){
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT * FROM users WHERE username = '$username' AND pass = '$password' ";
$result = mysqli_query($mysqli,$sql);
if (mysqli_num_rows($result)>0){
echo "Login Success!";
exit();
}
else{
echo "Login Failed";
exit();
}
}
?>
I expected to solve this problem on my own but i got totally confused and don't even know what i have tried so far and what else is there to be tried
Note: My password is md5 protected
Hey guys ive put together a basic user log in for a secure admin area and it seems to work great, if you enter a correct user/pass you get access, if you enter the wrong user pass, you get no access. However if you enter nothing in both fields you get access.
This is how it works.
Creating a user, a basic form POSTS to this php file.
<?php
$con = mysqli_connect(credentials are all good) or die(mysqli_error($con)) ;
$escapedUser = mysqli_real_escape_string($con, $_POST['user']);
$escapedPass = mysqli_real_escape_string($con, $_POST['pass']);
$some_str = md5(uniqid(mt_rand(), true));
$base_64str = base64_encode($some_str);
$modified_base64 = str_replace('+', '.', $base_64str);
$gensalt = substr($modified_base64, 0, 22);
$format_str = "$2y$10$"; // 2y for Blowfish and 10 times.
$salt = $format_str . $gensalt . "$";
$hashed_pass = crypt($escapedPass, $salt);
$query = "INSERT INTO `userpass` (`username`, `password`, `salt`) VALUES ('$escapedUser', '$hashed_pass', '$salt'); ";
if(isset($escapedUser) && isset($hashed_pass))
{
mysqli_query($con, $query);
header("Location: ausers.php");
exit();
}
Echo "Something went wrong!";
?>
The database appears to be storing these fine
We then log in with this code
<?php
$con = mysqli_connect(again credentials are fine) or die(mysqli_error($con)) ;
$escapedUser = mysqli_real_escape_string($con, $_POST['user']);
$escapedPass = mysqli_real_escape_string($con, $_POST['pass']);
$saltQuery = "select salt from userpass where username = '$escapedUser';";
$result = mysqli_query($con, $saltQuery);
$row = mysqli_fetch_assoc($result);
$salt = $row['salt'];
$hashed_pass = crypt($escapedPass, $salt);
if(isset($escapedUser) && isset($hashed_pass))
{
$userQuery = "SELECT * FROM userpass WHERE username='$escapedUser' AND password='$hashed_pass'";
$userpass = mysqli_query($con, $userQuery);
$count = mysqli_num_rows($userpass);
if($count == 1)
{
$_SESSION['username'] = $escapedUser;
header("location: aindex.php");
exit();
}
header("Location: alogin.htm");
exit();
}
Echo "Something went wrong!";
?>
So as i said, this seems to work fine for when any user pass combination is given whether access granted or denied however using no user and pass and pressing log in allows entry. Any ideas? THeres no blank rows in the database table.
Side question, is this salt/hash method correct, its my first attempt.
For your login code, your condition relies on an isset() test. You perform this test on $escapedUser and $hashed_pass. Both of these variables were actually assigned values earlier in the code! Once you assign a value to the variable, it will pass the isset() test, even if the value is an empty string. You might want to use an empty() check, perhaps on the original $_POST variables.
Moving on to the inner condition, which tests if the mysql query returns exactly 1 row of results. If there were truly no rows with empty values, then this condition would never pass because the query would return 0 rows. But it is passing. Two things to consider:
Notice that your registering code uses the same isset() test. Therefore it is very possible that someone used your registration form, submitted empty fields, and successfully registered a row with empty user and password fields. Have you explicitly queried your database for empty fields and actually come up with 0 results?
Your query uses SELECT *. Perhaps this is causing the query to return some sort of aggregate value (like a COUNT() or something that always has a result no matter what). Perhaps try explicitly defining the columns to return?
I cannot comment on your salt/hash method as I have no experience in that part. Hope you find this helpful!
In my opinion you need more than one level of checks in any form, whether it be registration, comments, login, etc. The way I prefer to go about it is a tiered approach. It may work better for you, but it's just an example.
By doing it this way, you ensure that your input will never be empty. Another issue I see with your login script is that you never compare the input with the database so how can you know if they entered the correct information? The only thing allowing them to login is that the query returned a record. This is also why they can login with a blank form.
<?php
$con = mysqli_connect(again credentials are fine) or die(mysqli_error($con)) ;
/* Ensures that form was submitted before any processing is done */
if (isset($_POST)) {
$User = $_POST['user']);
$Pass = $_POST['pass']);
if (!empty($User)) {
if (!empty($Pass)) {
$escapedUser = mysqli_real_escape_string($con, $User);
$escapedPass = mysqli_real_escape_string($con, $Pass);
/* you need to verify the password here, before adding the salt */
$saltQuery = "select salt from userpass where username = '$escapedUser'";
$result = mysqli_query($con, $saltQuery);
$row = mysqli_fetch_assoc($result);
$salt = $row['salt'];
$hashed_pass = crypt($escapedPass, $salt);
$userQuery = "SELECT * FROM userpass WHERE username='$escapedUser' AND password='$hashed_pass'";
/* you need to verify the username somewhere here */
$userpass = mysqli_query($con, $userQuery);
$count = mysqli_num_rows($userpass);
if($count == 1)
{
$_SESSION['username'] = $escapedUser;
header("location: aindex.php");
exit();
} else {
header("Location: alogin.htm");
exit();
}
} else {
echo "Please enter a password.";
}
} else {
echo "Please enter a username.";
}
} else {
echo "You have not entered any information.";
}
?>
I'm kinda new to the OOP(? If this IS OOP, I don't know) language, and I'm trying to make a simple login-proccess, with MySQLi. The problem are, that the code doesn't work. I can't login (and It's not showing me any errors) and I can't register an new account (same problem) - It's like the code are dead or something.
I'm not sure I've done it right, but this is my best, so far. 'cause I'm new to OOP(?).
Index.php:
<?php
if(isset($_POST['submit'])) {
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string(md5($_POST['password']));
$userControl = "SELECT * FROM users WHERE username='".$username."' AND password='".$password."'";
$userControlResult = $mysqli->query($userControl);
if($mysqli->num_rows($userControlResult) > 1) {
$userRow = $mysqli->fetch_assoc($userControlResult);
$dbid = $userRow['id'];
$dbuser = $userRow['username'];
$_SESSION['id'] = $dbid;
$_SESSION['username'] = $dbuser;
header("location: me.php");
die();
} else {
echo "<div class='errorField'>Användarnamnet eller lösenordet är fel!</div>";
}
}
?>
I suppose that if I can solve the first error, I can solve the second too.
Thanks!
Many things I would recommend changing about your code:
Don't use mysql_real_escape_string() if you're using mysqli. You can't mix these APIs.
No need to escape a string returned by md5(), because it's guaranteed to contain only hexadecimal digits.
Don't use mysqli_real_escape_string() anyway -- use parameters instead.
Always check if prepare() or execute() return false; if they do, then report the errors and exit.
You can get a mysqli result from a prepared statement using mysqli_stmt_store_result().
Don't SELECT * if you don't need all the columns. In this case, you already have $username so all you really need to fetch is the id column.
No need to check the number of rows returned, just start a loop fetching the rows (if any). Since you exit inside the loop, your "else" error clause will be output only if the loop fetches zero rows.
Consider using a stronger password hashing function than MD5. Also, add a salt to the password before hashing. Read You're Probably Storing Passwords Incorrectly.
Example:
<?php
if(isset($_POST['submit'])) {
$username = $_POST['username'];
$password = md5($_POST['password']);
$userControl = "SELECT id FROM users WHERE username=? AND password=?";
if (($userControlStmt = $mysqli->prepare($userControl)) === false) {
trigger_error($mysqli->error, E_USER_ERROR);
die();
}
$userControlStmt->bind_param("ss", $username, $password);
if ($userControlStmt->execute() === false) {
trigger_error($userControlStmt->error, E_USER_ERROR);
die();
}
$userControlResult = $userControlStmt->store_result();
while($userRow = $userControlResult->fetch_assoc()) {
$_SESSION['userid'] = $userRow["id"];
$_SESSION['username'] = $username;
header("location: me.php");
die();
}
// this line will be reached only if the while loops over zero rows
echo "<div class='errorField'>Användarnamnet eller lösenordet är fel!</div>";
}
?>
A good command to enter at the top of the script (under the
ini_set('display_errors', 1);
This will display any errors on your script without needing to update the php.ini (in many cases). If you try this, and need more help, please post the error message here and I'll be able to help more.
Also, if you are using $_SESSION, you should have
session_start();
at the top of the script under the
Make sure your php is set to show errors in the php.ini file. You'll need to do some research on this on your own, but it's fairly easy to do. That way, you'll be able to see what the error is and go from there.
Is there a way to make the username part work for both upper and lower case, for example if my username were robert if you entered Robert it would work as well? Attached is a copy of my login script.
<?php
session_start();
$username = $_POST['username'];
$password = $_POST['password'];
if ($username&&$password)
{
$connect = mysql_connect("localhost","*i*****5_******","*******") or die ("Couldn't Connect"); //host,username,password
mysql_select_db("virtua15_gateway") or die ("Could not find database");
$query = mysql_query("SELECT * FROM Users WHERE username='$username'");
$numrows = mysql_num_rows($query);
if ($numrows!=0)
{
while ($row = mysql_fetch_assoc($query))
{
$dbusername = $row['username'];
$dbpassword = $row['password'];
}
if ($username==$dbusername&&md5($password)==$dbpassword)
{
header( 'Location: index2.php' );
$_SESSION['username']=$dbusername;
}
else
echo "incorrect username and password";
}
else
die ("This user does not exist");
}
else
die("Please enter a username and a password")
?>
check strtolower($username) == strtolower($dbusername)
I'm a bit confused why you're checking it twice though. You've already checked in your sql query if the usernames match. Also, are your username's not unique? Why are you doing a while loop and not just a if (false !== ($row = mysql_fetch_assoc($query)) {}
Also, you should make sure your $dbusername and $dbpassword get defined because if a row is not found, they won't be, and PHP will issue a warning about undefined variables when you access them.
Also, you should be checking if the $_POST keys are set. I tend to code a bit paranoid, but I like to make notices/warning very hard to get. If your server were set to display errors, a user could see either a rather ugly error message, or potentially even sensitive data.
Also, while I'm being way overly picky, as per the HTTP specification, the Location header expects a full URL, not just a relative file name (though all browsers support just a relative file name).
Convert to either lower/upper case or make a case insensitive match.
Important
Please don't do this:
$username = $_POST['username'];
$query = mysql_query("SELECT * FROM Users WHERE username='$username'");
As it will allow hackers to perform SQL injection! Please sanitise ALL of your inputs!
IE,
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
Important
Edit :: Also, NEVER use PHP to do the job of php
$query = mysql_query("SELECT * FROM Users WHERE username='$username'");
Is wrong, you should perform the sql query with your login logic!
IE
"SELECT * FROM Users WHERE username='$username' AND password='" . md5($password) . '"
Then you can just say this instead
if(mysql_num_rows($query)){
// Login logic
}
Edit ::
SQL queries are case insensitive
hi try strtolower() function.
$username = strtolower($_POST['username']);
Check this http://php.net/manual/en/function.strtolower.php
You can check by two tyes:
while ($row = mysql_fetch_assoc($query))
{
strtoupper($dbusername) = strtoupper($row['username']);
$dbpassword = $row['password'];
}
OR
while ($row = mysql_fetch_assoc($query))
{
strtolower($dbusername) = strtolower($row['username']);
$dbpassword = $row['password'];
}
Use any one of them.
this will resolve your problem.
A working alternative in MySQL:
mysql_query(
"SELECT * FROM Users
WHERE LOWER( username) = LOWER( '" . mysql_real_escape_string( $username) . "')"
);
If your requirement is to allow login irrespective of the case , I mean Robert, robert, ROBERT, RoBeRT etc.. , then you can consider storing the username in lowercase in the database and while retrieving convert the username to lowercase and execute the query
Hello I facing a strange problem; I am using this code to check the login data with my db
include("includes/config.php");
include("includes/database.php");
$name = $_POST['username'];
$pass = $_POST['password'];
$sql = "SELECT * FROM info_user WHERE user_name = '$name' AND password = '$pass'";
$result = mysql_query($sql) or die(mysql_error());
$row = mysql_fetch_array($result) or die(mysql_error());
echo $row['user_name']. " - ". $row['password'];
if (mysql_num_rows($sql)) {
echo "success";
}
else
{
echo "failed";
}
here, when i succeed it shows success but any blank input or wrong input is not showing the failed message why? and how can I solve it? is there any better way to check the login? please help
Thanks in advance
First off:
$row = mysql_fetch_array($result) or die(mysql_error());
If you pass along a wrong username or password, mysql_fetch_array() will return FALSE, because there is no rows to take from. This results in your or die(mysql_error()) part being executed, which means your script dies and outputs nothing since mysql didn't fail - which again means that mysql_error() has nothing to return to you.
Secondly, you are using mysql_num_rows() on the $sql string, not on the $result variable which actually contains a mysql resource that you should be using.
You should also check the mysql_num_rows() before using mysql_fetch_array() so that you don't try to pull out some data you don't have available.
Lastly, your solution is full of security flaws. You are passing along raw post data to your mysql database which makes you vulnerable to sql injection and you are storing your passwords as plain text values in your database (not plain text files, just plain text values).
You should google sql injection and password hashing to improve your security.
Try this:
$num_rows = mysql_num_rows($result);
if ($num_rows > 0) {
echo "success";
} else {
echo "failed";
}