check if username is not taken between two tables - php

Well i have a problem. I have a registration for for legal users and natural users, but i need to write a validation in each php file for username checking, i have no idea how to combine two table checking.
one table is called users_legal, 2nd one is users_natural. In both forms name for input field is "username".
So far i have a code that checks passwords :
if ($password == $password_re)
{
// insert into table
$sql = $db->prepare("INSERT INTO users_legal(name, reg_number, address, phone, email, username, password) VALUES(?, ?, ?, ?, ?, ?, ?);");
$sql->bind_param("sssssss", $name, $reg_number, $address, $phone, $email, $username, $password);
$sql->execute();
$sql->close();
}
After makeing a validation in register forms, i also need it in login page. I figured out how to check if there is only and only one user with that username and that password, but i have no idea how to search them between tables.
login.php code :
if($_SERVER["REQUEST_METHOD"] == "POST") {
// username and password sent from form
$myusername = mysqli_real_escape_string($db,$_POST['username']);
$mypassword = mysqli_real_escape_string($db,$_POST['password']);
$sql = "SELECT id FROM login WHERE username = '$myusername' and password = '$mypassword'";
$result = mysqli_query($db,$sql);
$row = mysqli_fetch_array($result,MYSQLI_ASSOC);
$active = $row['active'];
$_SESSION['username'] = $myusername;
$count = mysqli_num_rows($result);
if($count == 1) {
session_register("myusername");
$_SESSION['username'] = $myusername;
$_SESSION['loggedin'] = true;
header("location: www.goole.lv");
}else {
$error = "Your Login Name or Password is invalid";
}
}
One more thing : i set my mysql to utf format, var_dump says that input is allright, but in mysql it saves in unbelievuble forms, like Ķegums or Skrīvelis.
Thnx for any examples, tips or whateva u got.

When I got you right, you have two tables with users. To validate if an user has logged in successfully you look up their login credentials in the related database table.
You are asking for 'combining' these two tables. But I don't think that that's what you want. You have two separate user tables. They do not belong to each other. If you join those tables, you might have dulicate unique user ids when combining these tables.
What you could do instead is check both tables separately, first for users_legal and second for users_natural.
You should also think about using password hashes instead of plain passwords in your db. And use pdo ;)
Good luck

To solve the problem of having two different types of users I would just put them in the same table and add a value that represents the user type for example 0 = legal and 1 = natural. This will also automatically prevent two users from sharing the same username. (This will only work for sure if the database is still empty, if not you might end up with two users with the same name). For the character encoding try setting mysql to utf-8 if you haven’t done it already (instead of just utf). Also you should never save passwords in plaintext. Use the sha1 function in php to convert them to their hash value before storing them. That way even if someone gets unauthorized access to the database they still won’t know the passwords. You should also append some user specific information to the password before hashing so that even if two users share the same password their hash values will be different. To verify if it’s correct you just apply the same procedure to the input before comparing it with the hash value you have stored.

Related

How to make my PHP files call the password from the database properly?

I am currently working on a website, it has a sign up PHP file that sends data to a database. For security measures, I set up a password encryption file that encrypts the password that the user enters, so that it is impossible to find in the database. Unfortunately, when the user tries to connect to the database from the log in PHP file, it denies them access to log in because the code connects to the database passwords, but it doesn't "sanitize" the password from it's encryption code, and the password isn't recognized by the server. I will provide my codes below:
Signup.php
$p = $_POST['p'];
$cryptpass = crypt($p);
include_once ("php_includes/randStrGen.php");
$p_hash = randStrGen(20)."$cryptpass".randStrGen(20);
Login.PHP
$p = md5($_POST['p']);
How do I change the Login.PHP line provided above so that it sanitizes the password from it's encryption value to the password the user actually knows and entered in the first place?
p.s. $p= The Password that the user enters
I'm going to add a second answer here, which is more of a safe guard when it comes to any user input you get that will be inserted or drawn from a database. When you MySql you want to sanitize any user input to prevent database injection which is the easiest way to break into a database.
Here is a great sanitation script. Start by making a separate PHP file and copy/paste this code into it.
<?php
// Sanitize User Input
function sanitize($data){
// apply stripslashes if magic_quotes_gpc is enabled
if(get_magic_quotes_gpc()){
$data = stripslashes($data);
}
// a mySQL connection is required before using this function
$data = mysql_real_escape_string($data);
return $data;
}
?>
Now include this page on any page that you will be interacting with the db
<?php require("sanitize.php"); ?>
Note: Before calling the function you must already be connected to your db
IE: mysql_connect("mysql",$mysqlusername,$mysqlpassword);
From here on out it is very simple. Say you assign a variable from a post like so
$password = $_POST["password"];
To sanitize this input you would do this
$password = sanitize($password);
This helps prevent MySql injections by removing certain characters relevant to modifying or revealing database information.
Hope this helps!
Ok, so once you get the password from the user you will want to encrypt it when inserting into your database. This requires an extra piece of data that is called "salt".
Salt is unique and you decide what you want it to be. But you will need it to encrypt and decrypt so it's important you do not lose it! I keep it in its own file and use an include whenever I need it. The following is PHP
$key_salt = 'lettersandnumbers';
Now for the password encrypting
Say you have the username and password in variables like so...
$user_id = "usersId";
$password = "usersPassword";
This is the way to put them into the database...
Create a variable with the following data
$insertdata = sprintf("INSERT INTO $table (user_id, password,) VALUES ('%s', AES_ENCRYPT('%s', '$key_salt'))", $user_id, $password);
mysql_query($insertdata);
Notice the AES_ENCRYPT('%s', '$key_salt') This is what is making the encryption and see how it uses the $key_salt along with the '%s' (which is the $password)
The combination of these makes it nearly impossible to crack
This will decrypt the password and put it into a variable then you can do what you want with it after that....
$results = mysql_query("
SELECT AES_DECRYPT(password, '$key_salt') as password FROM $table where AES_DECRYPT(password, '$key_salt')='$password'");
$row = mysql_fetch_array($results);
$decryptedpassword = $row['password'];
Do not concatenate crypted password with random characters unless you save them also in database, otherwise - you will never be able to compare user input with saved encrypted password. Just use:
$p_hash = $cryptpass;
and in Login.php script do not use md5($_POST['p']); which is different hashing method, but use also crypt() function:
$p = crypt($_POST['p']);

Can using PHP "if" statements on the results of a SELECT query to determine whether to execute an INSERT query cause unintended data overlap?

I'm a student and this is my first time writing a piece of software. It's a web application on a LAMP stack, and as part of that web application, I wrote the following function to interact with the database when creating a new user:
public function CreateUser($username, $password, $email){
global $DBHandler, $SQLStatement;
$SQLStatement = $DBHandler->prepare("SELECT id FROM users WHERE username = :username AND verified > 0");
$SQLStatement->bindParam(':username', $username);
$SQLStatement->execute();
$check = $SQLStatement->fetch();
if ($check['id']){
return 2;
}else{
$SQLStatement = $DBHandler->prepare("SELECT id FROM users WHERE email = :email AND verified > 0");
$SQLStatement->bindParam(':email', $email);
$SQLStatement->execute();
$check = $SQLStatement->fetch();
if ($check['id']){
return 3;
}else{
/* Edited out code that generates a random verification code, a random salt, and hashes the password. */
$SQLStatement = $DBHandler->prepare("INSERT INTO users (username, email, passwordhash, salt, verifycode) VALUES (:username, :email, :passwordhash, :salt, :verifycode)");
$SQLStatement->bindParam(':username', $username);
$SQLStatement->bindParam(':email', $email);
$SQLStatement->bindParam(':passwordhash', $passwordhash);
$SQLStatement->bindParam(':salt', $salt);
$SQLStatement->bindParam(':verifycode', $verifycode);
$SQLStatement->execute();
return 1;
}
}
}
$DBHandler is initiated elsewhere as a PHP Data Object.
It follows these basic steps:
Query the database to see if someone has already verified an account with the desired username.
If the username is available, do another query and do the same check for email.
If both the username and the email are available, generate verify code, salt, hash the password, do a third query to write everything to the database, and return 1 (meaning success).
The idea is that usernames and emails aren't reserved until your account is verified (verified = '1'). Elsewhere there's a script that changes your verified column to '1' if you click an emailed verification link.
My first question is this:
Person A is proposing username "Lorem", and person B has an unverified account that also proposes the username "Lorem". Is it possible for the queries to be executed in the following order?
Person A's script determines the username "Lorem" isn't taken by a verified user
Person B's script verifies their account with username "Lorem"
Person A's script creates their unverified account with username "Lorem"
My second question is:
Is it possible to combine the 3 queries in this script into 1 query with the same if/else logic expressed in SQL instead of PHP, and if so, would that improve performance and/or prevent the above scenario from occurring?
For a more concurrent solution, you could make the insert conditional:
insert into users
(username, email, ...)
select :username, :email, ...
where not exists
(
select *
from users
where verified > 0
and (username = :username
or email = :email)
)
This is still not 100% safe in MySQL, but should suffice in practice.
Note that the problem of concurrency in user creation is a luxury problem. I'd just set up a basic version like the one you have, and focus on the more interesting aspects of your website!

PHP Session using only a single PASSWORD field (no username)?

I have been searching the web for a good tutorial on creating a script that allows someone to use a "enter password" field, and it then proceeds to allow them to access certain PHP pages.
I can only find tutorials that use both a USERNAME and PASSWORD (such as this tutorial- however i'm just looking for something that is secure, but uses one field only to authenticate.
Being a beginner, the only idea I have is to make the "username" field hidden, with the value of the actual username. I'm not sure how safe this is to do however, as i've heard it's dangerous to have hidden fields as they can be exploited?
I'm aware of SQL injection so i'm hoping to find something that is at least strong enough for that.
HTML:
<form action='login.php' method="post">
Password: <input type="password" name="password">
</form>
Login.php
<?php
// this password may come from any source.
// it's a variable for the sake of simplicity
$password = 'verySecretStuff';
if($_POST['password'] == $password){
//handle login
}else{
// handle no login
}
?>
If you just want to use a password, instead of a username+password combination, you just leave out the username part in the tutorials, so logging in would go like this:\
<?php
$password = 'unsafepassword1'; // received from a form post or whatever
$password = md5($password);
// Looking if this password is a valid password in the DB
$query = 'SELECT * FROM valid_passwords WHERE password = \''.$password.'\'';
IF(mysql_num_rows(mysql_query($query) == 1){
// user logged in
}
ELSE
{
// password was invalid
}
Just have a single input in your HTML (you don't need username at all):
<input type="password" name="password" />
And query the database as normal, just for the password:
$password = $_POST["password"];
$result = mysql_query("SELECT password FROM passwords WHERE password='" . some_hash_function($password) . "'");
if(mysql_num_rows($result) > 0) {
//There was a match
}
Update (based on comments on question)
If you want to allow access to multiple users with just a single widely known password, just store the password in your PHP script:
$password = "thePassword";
if(strcmp($password, $_POST["password"])) {
//Matched
}
Note that this is NOT particularly secure... the password is stored as plain text in the script. However, as you seem to want to multiple people to know the password, it's probably the simplest option. I would still suggest using a database to store the single password.
Well, the bad thing about it is that with username and password, you have to know the combination, user-password, with only password, it is easier to find out and a lot of users will just set some dumb passwords like: 654321 or birth date and stuff like that.
About the hidden fields, avoid them but if you really need it, use sessions instead.

PHP login, getting wrong count value from query / fetch array

EDITThanks to the comments below it has been figured out that the problem lies with the md5, without everything works as it should.
But how do i implent the md5 then?
I am having some troubles with the following code below to login.
The database and register system are already working.
The problem lies that it does not find any result at all in the query.
IF the count is > 0 it should redirect the user to a secured page.
But this only works if i write count >= 0, but this should be > 0 , only if the user name and password is found he should be directed to the secure (startpage) of the site after login.
For example root (username) root (password) already exists but i cannot seem to properly login with it.
<?php
session_start();
if (!empty($_POST["send"]))
{
$username = ($_POST["username"]);
$password = (md5($_POST["password"]));
$count = 0;
$con = mysql_connect("localhost" , "root", "");
mysql_select_db("testdb", $con);
$result = mysql_query("SELECT name, password FROM user WHERE name = '".$username."' AND password = '".$password."' ")
or die("Error select statement");
$count = mysql_num_rows($result);
if($count > 0) // always goes the to else, only works with >=0 but then the data is not found in the database, hence incorrect
{
$row = mysql_fetch_array($result);
$_SESSION["username"] = $row["name"];
header("Location: StartPage.php");
}
else
{
echo "Wrong login data, please try again";
}
mysql_close($con);
}
?>
The best thing you can do in such situations is trying to find out where the problem lies.
So, you could proceed by steps and do the following:
1) start your script with a print_r($_POST), to see what variables are passed by post (by absurd, the problem might even be related to the 'send' guard parameter you have ..IE a form being sent through get)
2) Assign your query to a variable (...and don't forget to escape parameters!) and print it to screen; and then exec it on mysql (or phpmyadmin) to see what results they give.
As a side note, as someone already pointed out, this code might be subject to SQL-injection, so you might consider using prepared statements; see here: quick intro
Your login code is good.
But you also need to use md5() function BEFORE storing the password in the database. So when you are inserting the user record in the DB , apply the md5() to the password , save in the DB. Now when you will try to find the record on login, it will match correctly.
You should rewrite this with mysqli or PDO and using a newer hash function as well as a salt. MD5 is very widely used and is a target for crackers.

check if username exists

Im making a registration script for my site and i want to check if $_POST['username'] does already exist in db.
Is there a better, less code way of doing it? I do the same for email.
This is how it looks like now:
$checkusername = mysql_query("SELECT username FROM users WHERE username = '$_POST[username]'");
$row83 = mysql_fetch_assoc($checkusername);
if ($_POST['username'] == $row83['username']) die('Username already in use.');
Add a unique constraint onto your table:
alter table users
add unique (username)
Then, your insert or update statements will fail out:
mysql_query("insert into users (username) values ('$username')")
or die('Username exists');
Of course, a bigger issue with your code is that you aren't preventing SQL injection. Your code should be:
$username = mysql_real_escape_string($_POST['username']);
mysql_query("insert into users (username) values ('$username')")
or die('Username exists');
since you are already checking the username in the sql call, then you really just need to see if a record is returned in the php side of things
$row83 = mysql_query($checkusername);
if (mysql_num_rows($row83) == 0) die('Username already in use.');
If you set username as "unique" in your database you can just go ahead and run the insert query, which will fail (which you can handle). The same goes for email - make it "unique".
This may come in handy.

Categories