Duplicate User accounts - php

I just recently asked a question and got my code fixed to the one below:
{
//Check if user already exists
$un_check = mysql_query("SELECT Username FROM users WHERE Username = '$un'");
if(mysql_num_rows($un_check) >0) {
echo "Username already exists";
}
else{
// Username Free
}
And when signing up it states that "username already exists" however, it still allows me to create the account anyway and it adds the same information to the database.
Is this a problem with my code or the database?

If you want to forbid entering the same values twice in a table create a unique index.
Checking for an existent entry is one thing - prohibiting that another row with same values can be inserted is another thing.
Adding such an index works like this:
ALTER TABLE `users` ADD UNIQUE `MY_UNIQUE_INDEX` ( `username` )

You can simply put the mysql query code that adds a user to the database inside the else block. This way, you will never insert into the database if the user already exists.

Another way is to murder the script. I mean, use the die(); function. This stops the script wherever you place it. You would want to insert it like this:
//Check if user already exists
$un_check = mysql_query("SELECT Username FROM users WHERE Username = '$un'");
if(mysql_num_rows($un_check) >0) {
echo "Username already exists";
die(); // Don't continue, as we don't want to insert a username
}
else{
// Username Free
}
Although this would work, if there is any other code that you still want to execute regardless of whether the username exists or not, simply place the code that inserts your users inside the else{} block as others have suggested.

Possible cases
Username is not unique in your database.
(If you don't want to change your table structure) Put the insert part of the code inside else statement.
if(mysql_num_rows($un_check) >0) {
echo "Username already exists";
}
else{
// insert new username
}
BTW don't use mysql_ functions. DEPRECATED

The problem is two fold.
First, strictly from the data storage - aka database - point of view, a problem is from poorly executed database design. If the username is a field that needs to be unique, then that should be declared in the database by adding a unique index to the username column. This creates the proper database design so no a new record cannot be added if the username value already exists in the table - hence the unique index.
Sencond, your code that is checking if the username exists. Is it still creating the account after you check the database for duplicates or are you just saying that you can duplicate usernames manually in the database? If the codes is still duplicating the user, then it could be because the result is an empty set - ie no results cuz no username exists and so it won't return number of rows so change > to >=.

I was Passed through the same problem and my solution was this
<?php
//Connection Script Start
$mysql_host = "localhost";
$mysql_user = "root";
$mysql_password = "*******";
$mysql_database = "db_name";
$connect = mysqli_connect($mysql_host, $mysql_user, $mysql_password, $mysql_database);
//Connection Script Ends
$un = "userabc";
$search = "SELECT * FROM table_name WHERE username='$un'";
$query = mysqli_query($connect, $search);
$i = mysqli_num_rows($query);
if($i==0){
//username free
}else{
echo "This username is already taken";
}
?>

Related

mysql problem using php when update table

This system is based on invitation codes, if u have a code that is present in the database you can submit the input therefore change a value in a row. There are 2 inputs, 1) Invitation Code (key), if exist in the database the user can submit the value 2)Name (user). I done the following code but it doesn't work, any suggestions?
<?php
//get value pass from form in login.php
$username = $POST['user'];
$password = $POST['key'];
//connect to the server and select database
mysql_connect("localhost", "...","...");
mysql_select_db("...");
// Query the database for user
$result = mysql_query("UPDATE invitation_keys SET name ='$username' WHERE key = '$password'";)
or die("Failed to query database".mysql_error());
$row = mysql_fetch_array($result);
if ($row['key'] == $password) {
echo "Login success!!!".$row['key'];
} else {
echo "Failed to login";
}
?>
When you are coding in PHP, var_dump($var) is your best friend.
So the first thing to do here, is to print the query.
You will see, that your $username and $password vars are NULL, because you missed the syntax of $_POST[].
After, you can put in var_dump what you want, and that's why its interesting, because you will debug faster with this.

How do i convince the code that the data i am trying to pull out of a MySQL database actually exists?

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

How do I double check my PHP signin form

I made a signin form that will look through the database and find a match to the user's credentials, but how do I fix this code so it will relocate the page if there is no match.
<?php
session_start();
include_once 'includes/dbh.php';
$username = $_POST['u_name'];
$password = $_POST['pwd'];
$sql = "SELECT * FROM users;";
$result = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_assoc($result)) {
if ($username == $row['username'] && $password == $row['password']) {
$_SESSION['username'] = $username;
header("Location: second_index.php?signinSuccessful");
}
if ($username != $row['username'] && $password != $row['password']) {
header("Location: index.php?NotSucessful");
}
}
I tried putting the code inside of the loop, but I know that can't work, and if I put it outside of the loop, It redirects even if the credentials are correct. Please help. Thanks
First of all, this is totally wrong, you're looping trough all the users to see if the user exist, instead of that sql statement try $sql = "SELECT * FROM users where user='$user' and password='$password'";
And to avoid any data breach in that sql statemen you have to serialize the user and pass like that before adding it to the statement
$user = mysql_real_escape_string($conn, $user);
$password =mysql_real_escape_string($conn, $password);
Then you only check if the fields aren't empty (which means the user exist)
You are getting all the users from the users table and checking each record manually in php.
The reason why your code doesn't work is because the while loop doesn't check all the users in user table. If the first record in the retrieved table data doesn't match with entered username and password, it will go to 2nd if block and redirect.
You should change your query to filter by user-entered values.
SELECT * FROM USERS WHERE USERNAME = 'username' AND PASSWORD='password'
And later check in php if any record is returned. If any record is returned, it is a valid user, else redirect the user to failed authentication page.
As a good practice, make sure to use parameterized query.
Update Replace the while loop and block with this.
if(mysqli_num_rows($result) > 0){
// valid user
}else{
// invalid user
}
Why do you need while loop in this case when you fetching data from database? Using sql and make the database fetch the only one correct answer, don't make server site do unnecessary work.
I propose just do simple fetch then if check, no need for while loop at all.
Your logic is always redirect to index.php when username password not correct so of course it will always do so when your while loop on server do not hit the correct user.

Creating an Admin product system in PHP - Authentication error

I'm creating an e-commerce website. I am working on an admin page that lets the "store manager" log in to do things like add or remove products. In my database, I created a table called admin, with these fields:
id
password
time_last_logged_in
I inserted a row for my store manager, I can see the username and password so I know the person exists in the database, but when I try to log in it echoes out the error below.
admin_login.php
<?php
session_start();
if (isset($_SESSION["manager"])) {
header("location: index.php");
exit();
}
?>
<?php
if (isset($_POST["username"]) && isset($_POST["password"])) {
$manager = preg_replace('#[^A-Za-z0-9]#i', '', $_POST["username"]); // filter everything but numbers and letters
$password = preg_replace('#[^A-Za-z0-9]#i', '', $_POST["password"]); // filter everything but numbers and letters
// Connect to the MySQL database
include "../scripts/connect_to_mysql.php";
$sql = mysql_query("SELECT id FROM admin WHERE username='$manager' AND password='$password' LIMIT 1"); // query the person
// ------- MAKE SURE PERSON EXISTS IN DATABASE ---------
$existCount = mysql_num_rows($sql); // count the row nums
if ($existCount == 1) { // evaluate the count
while($row = mysql_fetch_array($sql)){
$id = $row["id"];
}
$_SESSION["id"] = $id;
$_SESSION["manager"] = $manager;
$_SESSION["password"] = $password;
header("location: index.php");
exit();
} else {
**echo 'That information is incorrect, try again Click Here';**
exit();
}
}
?>
I use a connect_test.php script to verify that it's connecting to the database and that there's no problem connecting.
index.php
<?php
session_start();
if (!isset($_SESSION["manager"])) {
header("location: admin_login.php");
exit();
}
// Be sure to check that this manager SESSION value is in fact in the database
$managerID = preg_replace('#[^0-9]#i', '', $_SESSION["id"]); // filter everything but numbers and letters
$manager = preg_replace('#[^A-Za-z0-9]#i', '', $_SESSION["manager"]); // filter everything but numbers and letters
$password = preg_replace('#[^A-Za-z0-9]#i', '', $_SESSION["password"]); // filter everything but numbers and letters
// Run mySQL query to be sure that this person is an admin and that their password session var equals the database information
// Connect to the MySQL database
include "../scripts/connect_to_mysql.php";
$sql = mysql_query("SELECT * FROM admin WHERE id='$managerID' AND username='$manager' AND password='$password' LIMIT 1"); // query the person
// ------- MAKE SURE PERSON EXISTS IN DATABASE ---------
$existCount = mysql_num_rows($sql); // count the row nums
if ($existCount == 0) { // evaluate the count
echo "Your login session data is not on record in the database.";
exit();
}
?>
Why might my code return That information is incorrect, try again Click Here'; instead of a successful validation?
The Problem(s?)
The way I see it, there are several problems with your code. I'll try to address each one and tell you how to solve each issue.
Issue #1: You are using REGEX To strip your code.
There are much better alternatives, the best of which is prepared statements which you should obviously use. Sadly, mysql_* functions don't support it. Which get's me to the next issue:
Issue #2: You are using mysql_* functions.
You shouldn't be using functions like mysql_query() and mysql_num_rows(), instead, consider moving to a better and more secure alternative, such as MySQLi (Good) or PDO (Awesome).
Issue #2.5: You are not using prepared statements.
A Prepared statement is automatically escaped and any malicious code or characters is render useless, same goes for SQL injections. You should use a better database handler that supports it (See Issue #2).
Issue #3: You are testing specifically.
You seem to test only if the row count is equal to exactly one. But what if there are (by accident) 2? Instead of testing what should be, test for what should not be:
if ($existCount != 0) { ...
Issue #4: You are not selecting the correct fields.
You only select the id field in your query, where instead you should be selecting all of the relevant fields (like username and password), in order to receive information.
Issue #5: You are not using secure storing.
If someone were to steal your database, they would have easy access to all your passwords. Consider using an encrypting method like sha1().
Issue #6: You are not testing for errors.
Errors can and will occur, you should test for them, with mysql_query() you should probably do something like
mysql_query("SELECT....") or die(mysql_error());
In PDO that would be something like
if (!$stmt->execute()) { throw new Exception("Execution failed.` . var_export($stmt->errorInfo(), true)); }
Try to correct those, and tell us if your problem persists.
Good luck :)
Try doing:
$sql = mysql_query("SELECT ... LIMIT 1") or die(mysql_error());
Your code assumes the query succeeds, which is very bad form. Always check for error conditions. You may have failed to connect to the database. perhaps your DB is malformed and you've got 2 or more records with the same username/password combo, etc...
I'm new to PHP myself, but I noticed that your select statement in the first code sample above selects only the id. That might be the problem. You should change it to select * and see if that makes any difference.
Good luck

How do I check a table to see if a string is already in use?

I am using this code to check my username column (username is primary) in my userdb table to see whether or not the string is already there. If it isn't there then it adds the string entered from a previous form into the username column in my table. But if it is there then it says "(Username) is already in use!".
This works when I put an entry in the username column such as "Sam" and then when I enter Sam into the previous form. But if I have "Sam" in the username column and then enter sam with all lowercase into the previous form, it displays Duplicate entry 'sam' for key 1.
I just want it to say that the string is already in use no matter what kind of casing I enter into the previous form.
$result = mysql_query("SELECT username FROM userdb") or die(mysql_error());
$row = mysql_fetch_array( $result );
$checkuser = $row['username'];
if ( $checkuser == $username ) {
echo "<font color='red'>" .$username. "<font color='black'> is already in use!";
die(mysql_error());
} else {
mysql_query("INSERT INTO userdb (username, password) VALUES('$username', '$password' ) ") or die(mysql_error());;
echo "Data Inserted!";
}
You shouldn't do it this way, because it can lead to race conditions. That's what happens if, between your check and your insert, somebody else inserts that username into the table.
The correct way to do it is to have a primary key on the username and insert the record, catching an exception or error code returned from the DBMS.
If the username is already in there, it won't be inserted again and you'll catch the error.
If it's not there, it will be inserted and you'll get no error.
In terms of your casing problem, I'd either convert all user names to lowercase before insertion or checking, or insert the mixed-case version and lower-case both the DB copy and local copy in all checks.
Change the code to:
strtolower($checkuser) == strtolower($username)
$result = mysql_query("SELECT count(*) FROM userdb where UCASE(username)=UCASE($checkuser);"
Check the number of rows in the result.
Pseudocode:
If num_rows>0
Username exists;
The short answer is:
If you want the usernames to be case-insensitive, you need to store them in the database in a case-insensitive manner. Convert the given username to all lower-case (or all upper-case) first.
$lcusername = strtolower($username);
Then use $lcusername wherever you use $username in the code you supplied.
The long answer is:
You don't need to check for the pre-existence of a key in a table. Assuming you have a PRIMARY KEY attribute on the username field, simply try to your data into the table (after converting it to lower-case). If the database returns a "duplicate key" error, you know the username already existed and you can display the error message. If the database returns that it successfully inserted the row (perhaps by using the mysql_affected_rows function). This saves you from having to do a SELECT before doing the INSERT, greatly simplifying your code.
You should also escape all the strings that you'll be inserting into the table to help avert potential security holes.
$lcusername = strtolower($username);
// Escape strings
$esclcusername = mysql_real_escape_string($lcusername);
$escpassword = mysql_real_escape_string($password);
mysql_query("INSERT INTO userdb (username, password) VALUES('$esclcusername', '$escpassword') ");
if (mysql_affected_rows() == -1) {
// Display error message
} elseif (mysql_affected_rows() == 1) {
// Yay! Insert successful
} else {
// Affected rows is 0. Something went wrong
}
The only way to do this correctly and avoid race conditions* is attempt to insert the user's data and examine any errors to see if the error is a duplicate key error. If you were using PDO (you should be) it would throw an exception which you could catch and examine. I think you can still trap and examine errors using PHP's standard error handling, I'm just not sure how.
*The race condition here is this:
Check user name is unique, it is.
Another user creates an account with that username
You now attempt to create an account with that username for the original user, which causes an error.

Categories