This has surely come up before but I haven't found a solution. I am trying to select username and password from a database to verify users a simple login script. It should simply find a row in the users table with a username and password matching those submitted through the login form.
I can match the username without any problem but not the password and I have no idea why.
The table contains columns called "username" and "password" and there is only 1 row in the table with a username 'admin' and a password 'testpassword'.
Here is the function containing three options - options 1 and 4 work, the other two don't. Option 2 is the same as option 1 except it looks up a different column. I have checked that the column name in the query matches the columns in the table and that the submitted values match. I'm not getting any error messages and can't see what might be wrong (something basic, I'm sure...).
function new_session ($username, $pw, $inactive) {
// echo statements verify that variable match database values
echo "<h2>username = " . $username . "</h2>";
echo "<h2>password = " . $pw . "</h2>";
echo "<h2>inactive = " . $inactive . "</h2>";
$db = mydb::getConnection();
//option 1
$statement = $db->prepare('SELECT * FROM users WHERE username = :parameter');
$statement->bindValue(':parameter', $username);
//option 2
//$statement = $db->prepare('SELECT * FROM users WHERE password = :parameter');
//$statement->bindValue(':parameter', $pw);
//option 3
//$statement = $db->prepare('SELECT * FROM users WHERE password = :parameter1 AND username = :parameter2');
//$statement->bindValue(':parameter1', $username);
//$statement->bindValue(':parameter2', $pw);
//option 4
//$statement = $db->prepare('SELECT * FROM users WHERE username = "admin" AND password = "testpassword"');
$statement->execute();
$row = $statement->fetchAll();
if (count($row) == 1) {
// SESSION data is set here for options 1 and 4
}
}
First thing you need to check is if the passwords in your data base are hashed. They probably should be, and if they are you need to compare using the hashing function PASSWORD
$statement = $db->prepare('SELECT * FROM users WHERE password = PASSWORD(:parameter)');
$statement->bindValue(':parameter', $pw);
Now, if your passwords aren't hashed (shame on you), you might have a different problem. As you can see in the above, password is a function name in mysql. It might be having problems parsing your statement because you are using password as a column name. Put tick-marks around the column name password. Like this:
$statement = $db->prepare('SELECT * FROM users WHERE `password` = :parameter');
$statement->bindValue(':parameter', $pw);
Notice that those are tick marks, not a single quote. They are found on the same key that ~ is on, above the tab key. These tick marks will indicate that password is a column name.
The word "PASSWORD" is a mysql command. so escape it first like this:
//option 3
//$statement = $db->prepare('SELECT * FROM users WHERE `password` = :parameter1 AND username = :parameter2')
If this query gives error, then I think you have your password encoded.
Then use this for md5:
$statement->bindValue(':parameter', md5($pw));
And for sha1:
$statement->bindValue(':parameter', sha1($pw));
I see no other errors which might could result in no rows :o
Thanks for all the suggestions and taking time to look at this, I have escaped the word password as suggested however I'm ashamed to say the problem was that the maxlength on my password form input was trimming the last character and I didn't spot it.
Related
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 3 years ago.
I'm trying to check the database for a taken username when the user signs up. The connection to the database works fine as a similar password will be added to the table.
$username = $_POST['user'];
$password = $_POST['password'];
$hash = password_hash($password, PASSWORD_DEFAULT);
$s = 'SELECT * FROM users WHERE username = "$username"';
$result = mysqli_query($con, $s);
$num = mysqli_num_rows($result);
if ($num == 1) {
echo "Username is taken";
}else {
table for users
It goes to the else and adds the username to the database anyways. I have checked to make sure there isn't more than one username, although a greater than sign would work better anyway. any ideas?
Your code must be using parameter binding to send the value of $username to the database, otherwise "$username" is treated as a literal string. It will also protect your from SQL injections.
It would probably be better to create a UNIQUE key on that column instead. If you want to do it in the application layer for whatever reason, you can fetch the result and use that.
$stmt = $con->prepare('SELECT * FROM users WHERE username = ?');
$stmt->bind_param('s', $username);
$stmt->execute();
$result = $stmt->get_result()->fetch_all();
if ($result) {
echo "Username is taken";
} else {
// No such username in the database yet
}
This is not going to be very efficient, so we can simplify it using COUNT(1). It will return a single value containing the number of matching rows.
$stmt = $con->prepare('SELECT COUNT(1) FROM users WHERE username = ?');
$stmt->bind_param('s', $username);
$stmt->execute();
$usernameTaken = $stmt->get_result()->fetch_row()[0];
if ($usernameTaken) {
echo "Username is taken";
} else {
// No such username in the database yet
}
For more explanation see https://phpdelusions.net/mysqli/check_value
$s = 'SELECT * FROM users WHERE username = "$username"';
You are using double quote inside single quote so there is no interpolation happening. Change the order to
$s = "SELECT * FROM users WHERE username = '{$username}'";
I'm trying to do a simple login, which compares the input of the ID and password by the user with the data in the database
//getting the inputs
$checkid = $_POST["id"];
$checkpassword = md5($_POST["pass"]);
//getting the id and password of the id and password of the inputs
$query = "SELECT id, password FROM login WHERE id=$checkid AND password=$checkpassword";
$res = mysqli_query($link, $query);
$nres = mysqli_num_rows($res);
//$nres should be 0 if the user inputs the right id but the wrong password
//or viceversa, the only way that it $nres!=0 is that both inputs match the db, right?
if ($nres == 0) {
header('Location: http://localhost:8888/login/login_fail.php');
else
header('Location: http://localhost:8888/profile/profile.php');
exit();
it doesn't work, even if i put the right ID and the password that are on the database it will redirect to login_fail.php.
Note: it does work if i do it just with he ID and take out of the query " ,password" "AND password = $checkpassword". Help
Add quotes to your variables:
"SELECT id, password FROM login WHERE id='$checkid' AND password='$checkpassword'"
^ ^ ^ ^
Sidenote: Don't use md5, it's now insecure to use as password storage.
For password storage, either use bcrypt or PHP's password() function.
And see this article also
Also noted in comments by others, use mysqli_real_escape_string():
$checkid=mysqli_real_escape_string($link,$_POST['id']);
Try the query:
$query = "SELECT id, password FROM login WHERE id='".$checkid."' AND password='".$checkpassword."'";
I've been modifying my code but I still can't log in... I have a MySQL database with a database called "users" with a table called "Users" and the following rows "UserNameID", "userName" and "password". I have created just an entry in order to test that:
+------------+----------+-----------+
| UserNameID | userName | password |
+------------+----------+-----------+
| 1 | root | pass |
+------------+----------+-----------+
Here my code:
<!DOCTYPE html>
<?php session_start(); ?>
<html>
<head>
<title>File1</title>
</head>
<body>
<?php
$DB_connection = mysqli_connect("localhost","user1","user1","users") or die("ERROR. Failed to connect to MySQL." . mysqli_error($DB_connection));
function SignIn() {
$usr = $_POST['user'];
$pw = $_POST['pwd'];
if(!empty($usr)) {
$query = mysql_query("SELECT * FROM Users where userName = '$usr' AND password = '$pw'");
$result = mysqli_query($DB_connection,$query);
if($result) {
while($row = mysqli_fetch_array($result)) {
echo "SUCCESSFULLY LOGIN TO USER PROFILE PAGE..."; }
} else {
echo "SORRY... YOU ENTERD WRONG ID AND PASSWORD... PLEASE RETRY..."; } }
}
SignIn();
mysqli_close($DB_connection);
?>
</body>
</html>
When I introduce a wrong password or username, it gives me "SORRY... YOU ENTERD WRONG ID AND PASSWORD... PLEASE RETRY...". However, it throws me the same when I put the correct password and username. What is wrong in my code?
Thanks a lot!
There numerous issues here. There are scoping issues, you are using the wrong methods, it's unsafe.
First off, these 2 lines:
$query = mysql_query("SELECT * FROM Users where userName = '$usr' AND password = '$pw'");
$result = mysqli_query($DB_connection,$query);
That's not how you query a database. You only need to call either mysql_query or mysqli_query depending on what API you are using. You are using MySQLi in this case, so do this:
$query = "SELECT * FROM Users where userName = '$usr' AND password = '$pw'";
$result = mysqli_query($DB_connection,$query);
Second, your SignIn function can't access the $DB_connection variable, it's out of scope. You need to pass it in:
function SignIn($DB_connection){
}
SignIn($DB_connection);
Third, this code is very unsafe! Never use $_POST directly in an SQL query like that. You should never be concatenating variables into an SQL string, you should use prepared statements.
// Don't use "SELECT *", use the fields you want
$query = mysqli_prepare($DB_connection, 'SELECT user_id FROM Users where userName = ? AND password = ?');
// This sends the values separately, so SQL injection is a thing of the past
mysqli_stmt_bind_param($query, 'ss', $usr, $pw);
// Run the query
mysqli_stmt_execute($query);
// Prepared statements require to define exactly the fields you want
mysqli_stmt_bind_result($query, $user_id);
// Get the data
while(mysqli_stmt_fetch($query)){
echo $user_id;
}
mysqli_stmt_close($query);
Lastly, storing plaintext passwords is bad practice. Use a hashing library. PHP 5.5+ has one built-in (http://php.net/password). There's also a version for lesser PHP versions (https://github.com/ircmaxell/password_compat).
P.S. As pointed out in the comments (here's a link), your session_start() is in the wrong spot. That sends a header, so it requires that there be nothing echoed out before it.
<?php session_start(); ?>
<!DOCTYPE html>
<html>
Make sure that there is no whitespace (or anything) before the session_start().
Your problem is here:
$query = mysql_query("SELECT * FROM Users where userName = '$usr' AND password = '$pw'");
This should instead be
$query = "SELECT * FROM Users where userName = '$usr' AND password = '$pw'";
You're then passing the query string rather than a resource to mysqli_query.
(Also, refer to Shankar Damodaran's answer regarding the scope issue: pass $DB_connection to the SignIn function).
As a side note, you shouldn't use posted data directly into the query. You're at risk of SQL injection. Look into sanitizing the data or, preferably, prepared statements.
First of all, you are running into scope issues here.
In this line...
$result = mysqli_query($DB_connection,$query);
The variable $DB_connection is not accessible inside your SignIn() and thus your query is getting failed. Also you are mixing mysql_* (deprecated) functions with mysqli_* functions.
This simple and small code snippet for the login might help you..
$con = mysqli_connect("localhost","user1","user1","users") or die("ERROR. Failed to connect to MySQL." . mysqli_error($con));
$username = $_POST['username'];
$password = $_POST['userpassword'];
$result = mysqli_query($con,"SELECT * FROM users WHERE user_name = '$username' and user_password='$password'");
$count=mysqli_num_rows($result); // get total number of rows fetched. needs only 1 row for successful login.
if($count==1){
//Login successful
}
else{
//Login unsuccessful
}
It will fetch a row if the entered username and password are matched.It will fetch only one row as the username and password will be unique. If the count of rows fetched is '1' you can have successful login.
On a recent project I am having issues when matching a password in the database.
The query is as follows:
mysql_query("SELECT * FROM user_accounts WHERE username = '$username' AND password = '$encryptedPass'")
This outputs
SELECT * FROM user_accounts WHERE username = 'T-McFarlane' AND password = 'äê1\Y¸c'
It can find me with just the user but with the password it cannot. I have echoed out both the database password and the encrypted password provides and they are exactly identical - this is what is in the database but it cannot find the matching row.
My question is that does this password contain any special characters or would there be any other reason that this is failing?
I have tried both utf8_swedish_ci and latin1_swedish_ci for my collation setting in the database.
You need to escape special characters in the string:
$username = mysql_real_escape_string($username);
$encryptedPass = mysql_real_escape_string($encryptedPass);
mysql_query("SELECT * FROM user_accounts WHERE username = '$username' AND password = '$encryptedPass'")
However, it would be even better to switch to PDO or mysqli, and use parametrized queries.
This question already has answers here:
How to check username and password matches the database values
(3 answers)
Closed 11 months ago.
I have a form which has a textbox with the name attribute username and another one with the name attribute password.
I also have a database with columns called user and pass. When my users signed up it added the username to the user column and password to the pass column.
How would I make a MySQL query to check if the form submitted the right username and password and then if it did have a branch to let me input the code for if it succeeded?
I really need some code, this bit isn't going well I know it should be something like SELECT * FROM table WHERE username == $username AND... but then I'm stuck because I have an MD5 password in the database and that first bit is probably wrong. Please help. :)
Thanks
//set vars
$user = $_POST['user'];
$pass = md5($_POST['pass']);
if ($user&&$pass)
{
//connect to db
$connect = mysql_connect("$server","$username","$password") or die("not connecting");
mysql_select_db("users") or die("no db :'(");
$query = mysql_query("SELECT * FROM $tablename WHERE username='$user'");
$numrows = mysql_num_rows($query);
if ($numrows!=0)
{
//while loop
while ($row = mysql_fetch_assoc($query))
{
$dbusername = $row['username'];
$dbpassword = $row['password'];
}
else
die("incorrect username/password!");
}
else
echo "user does not exist!";
}
else
die("please enter a username and password!");
Instead of selecting all the columns in count count(*) you can limit count for one column count(UserName).
You can limit the whole search to one row by using Limit 0,1
SELECT COUNT(UserName)
FROM TableName
WHERE UserName = 'User' AND
Password = 'Pass'
LIMIT 0, 1
1.) Storage of database passwords
Use some kind of hash with a salt and then alter the hash, obfuscate it, for example add a distinct value for each byte. That way your passwords a super secured against dictionary attacks and rainbow tables.
2.) To check if the password matches, create your hash for the password the user put in. Then perform a query against the database for the username and just check if the two password hashes are identical. If they are, give the user an authentication token.
The query should then look like this:
select hashedPassword from users where username=?
Then compare the password to the input.
Further questions?