How to build restriction on user availability during registration using PHP? - php

I have code that registers users by providing their username, email and password. Now I want to restrict the users to allow only if new username that are not saved into the database. If he/she inputs new username then message should alert notifying that the username you have entered is not available.
The code I have used is below in register.php
<?php
include"connection.php";
if (!isset($_POST['submit'])) //if the user clicks the submit button then the PHP code POST the details
{
$user_name = $_POST['username'];
$user_password = $_POST['password'];
$user_email = $_POST['email'];
if($user_name && $user_password && $user_email)
{
$query = mysql_query("INSERT INTO users (username, password, email, type)
VALUES ('$user_name', '$user_password', '$user_email', '0')");
mysql_query($query);
echo '<script type="text/javascript">alert("You have been registered");</script>';
}
else {
echo '<script type="text/javascript">alert("All fields required");</script>';
header("location:user_create.html");
}
}
?>

First of all:
filter data! Users can send unsafe data, so you should use mysql_escape_string() function (it's minimal requirement). Read about SQL Injection and XSS.
hash password! Minimal requirement is to use md5 function, read about password hashing: http://www.php.net/manual/en/faq.passwords.php
Use SQL query to check if user login is available:
$result = mysql_query('SELECT * FROM users WHERE username="'.mysql_escape_string($_POST['username']).'"');
if(mysql_fetch_array($result)) {
// username is unavailable, do something ....
}
else {
// register user
}
Notice, that mysql function are deprecated from PHP 5.5. Use PDO functions instead.

Use a UNIQUE key in the db for the username field. Then you can use mysql_error() to catch the error and to show user that he can't use that username because it is already stored in the db.

Related

Simple and efficient Login mechanism using PHP and database

I want to create a simple login system in my website I am developing for academic purpose.
This is what I did so far:
A user will have to fill out a form to input their username and
password, and then submit the form (POST method). Both vars will be sanitized.
Query from database
SELECT id FROM user WHERE username = x AND
password = y
Where x and y are username and password acquired using
$_POST['variable_name']
Then I used PHP function rowCount(). If the result = 1 (and only one), then that user will be notified that the login process is successful and a user id session var will be set.
So, is this kind of login system simple and efficient enough? I don't need any additional security measure (like password hashing) right now.
This is how it should be done with more modern standards:
$db = new PDO('mysql:host='.$database_host.';dbname='.$database_name.';charset=utf8', $database_user, $database_password);
$stmt = $db->prepare("SELECT id FROM users WHERE username=? AND password=?");
$stmt->execute([$_POST['username'], $_POST['password']]);
$user = $stmt->fetch(); // Or fetchColumn() to get just the id
if($user) {
// Login
} else {
// The user doesn't exist or the password is wrong
}
Use PDO or mysqli for prevention of sql injection and fast data retrieval
here is the code
<?php
$avail=0;
require 'connect.php';
if(isset($_POST['Submit']))
{ $Username=$_POST['Username'];
$Password=$_POST['Password'];
$query=$handler->query('Select * FROM users');
while($r=$query->fetch(PDO::FETCH_ASSOC)){
$U=$r['Username'];
$P=$r['Password'];
if($U==$Username&&$P==$Password){
$avail=1;
}
}
if($avail==1){
echo("<script>window.location = 'welcome.html';</script>");
}
if($avail==0){
echo("<script>alert('Wrong Username or Password')</script>");
}
}
?>

PHP - Comparing what the user entered to data in a database

I've got a simple contact form which posts two variables to PHP, to which I then insert to a database like so.
<?php
$username = $_POST["username"];
$password = $_POST["password"];
$db->query("INSERT INTO users (username,password) VALUES ('$username', '$password')");
?>
I've now created login.php, where I would like the user to be able to login using the information stored in the database. I'm not worried about security or anything, I'm just trying to ease myself into this. What would be the most simplest way to allow the user to login using their username and password?
error_reporting(0);
session_start();
include_once '../example.php';
/***************************** Step 2 ****************************/
if(isset($_REQUEST['admsubmit']))
{
$result=executeQuery("select * from adminlogin where admname='".htmlspecialchars($_REQUEST['name'],ENT_QUOTES)."' and admpassword='".md5(htmlspecialchars($_REQUEST['password'],ENT_QUOTES))."'");
// $result=mysqli_query("select * from adminlogin where admname='".htmlspecialchars($_REQUEST['name'])."' and admpassword='".md5(htmlspecialchars($_REQUEST['password']))."'");
if(mysqli_num_rows($result)>0)
{
$r=mysqli_fetch_array($result);
if(strcmp($r['admpassword'],md5(htmlspecialchars($_REQUEST['password'],ENT_QUOTES)))==0)
{
$_SESSION['admname']=htmlspecialchars_decode($r['admname'],ENT_QUOTES);
header('Location: admwelcome.php');
}else
{
echo "Check Your user name and Password.";
}
}
else
{
echo "Check Your user name and Password.";
}
closedb();
}
Go through the above code..its a simple example of check log in page post redirection by log in credentials form.
Assuming you don't want any security. I would do something like this:
$db->query("SELECT * from `users` where username = :username AND password = :password");
Replace the username and password with the user input.
WARNING: Don't use this on production environment. It's SQL injection vulnerable.
And you execute the query, Check the query row count, if it's equals to 1, it means there is a user with that username and password. if it equals to 0 it means, it's not found. You can then display errors or whatever.
Something like this in pseudo-code:
if(rowCount == 1) {
// log the user in
}
// Invalid credentials. Print some errors.
If you want security, Use PDO or mysqli functions. because mysql_* functions are deprecated and no longer maintained. and consider hashing your passwords, by using password_hash API.

username and password validation in php mysql

What I want to be able to do is: When a user enters their username and password in the form on the index.html page, if they match what is in the DB, then they get sent to the next page; userlogin.php.
If their username or password is incorrect then they are asked to re-enter their details on the index.html page, and displaying an error like, "Your username is Incorrect" or "Your password is Incorrect" above the form text box. I can paste this code if required.
Can I change this text font color as well, to red for example?
This is the code I currently have for the userlogin.php page
<?php
mysql_connect("Server", "root", "Gen") or die("Couldn't select database.");
mysql_select_db("generator") or die("Couldn't select database.");
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT * FROM users WHERE Username = '$username' AND Password = '$password' ";
$result = mysql_query($sql) or die(mysql_error());
$numrows = mysql_num_rows($result);
if($numrows > 0)
{
echo 'Your in';
}
else
{
echo 'Your not in';
}
?>
There as sooo many things wrong with this code:
1- you have an SQL injection hole.
If I enter ' or 1=1 LIMIT 1 -- as a username, I will always get access, no matter what.
Change your code into.
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
See: How does the SQL injection from the "Bobby Tables" XKCD comic work?
2- you are storing the password in the clear
This is a huge no no. Combined with the SQL-injection hole, it will take a hacker 5 minutes to get a list of all usernames and passwords on your site.
Store the password as a salted hash.
I like to use the username as the salt.
You store the password hash using:
INSERT INTO users (username, passhash)
VALUES ('$username', SHA2(CONCAT('$password','$username'),512))
And you test the user credentials using:
SELECT * FROM users
WHERE username = '$username' AND
passhash = SHA2(CONCAT('$password','$username'),512)
See: Secure hash and salt for PHP passwords
And: What is "salt" when relating to MYSQL sha1?
BTW, use SHA2 with a 512 keylength, SHA1 is no longer secure, and MD5 is even more broken.
3- A login can only ever match against 1 user
This code:
if($numrows > 0)
Makes no sense, if you get 2 rows out of the database, that's a clear sign someone has hacked your system. The test should be:
if($numrows > 1) { //send email to sysadmin that my site has been hacked }
else if ($numrows = 0) { echo "wrong username or password" }
else { echo "welcome dr. Falken" }
4- Don't die if there's an error, call a routine to restart the connection or something
This code:
$result = mysql_query($sql) or die(mysql_error());
Is fine in testing, but in production you should do something like
$result = mysql_query($sql);
if ($result) {
//do the deed
} else {
//call error recovery routine
}
The error recovery routine should reconnect to the server, log a error in the logbook. Is the error cannot be fixed, it should send an email to the sysadmin and only then die the server.
First of all, your code is vulnerable to SQL injection. Use PDO and prepared statements to fix this. Second of all, you're appearantly storing usernames unencrypted. This is very unsafe. Use a hashing function to encrypt the passwords, and encrypt the submitted password before running the query to get a match. Coloring the output is simple:
echo '<span style="color:red">Your not in</span>';
And use sessions to actually log the user in. After successfully querying the user table for the username/password combination, store the returned user_id in the $_SESSION variable. On each page that needs to be secured, just check for the existence of $_SESSION['user_id']; if it isn't there, your user needs to login so redirect him to the login form.
That should about do the trick for ya ;)

can't pull info form database that uses PASSWORD() function

I have this user login process page. at this point the user has entered the info and all of this works BUT I cannot figure out how to pull the encrypted password out of the DB. I need to extract with the PASSWORD() function and do not know how. I know this is not the best way to do it but its what the assignment calls for. I have the problem section commented out I think thats what needs fixing.
//sets $query to read usnername and passowd from table
$query = "SELECT username,password,first_name,last_name FROM jubreyLogin WHERE username
= '$userName' AND password=password('$userPassword')";
$result = mysql_query($query,$db);
if(mysql_error())
{
echo $query;
echo mysql_error();
}
//reads data from table sets as an array
//checks to see if user is already registered
while($row=mysql_fetch_array($result))
{
if($userName == $row['username'] /*&& $userPassword == ($row['password'])*/)
{
$login = 'Y';
$welcome = "Welcome" . " " .$row['first_name']. " " .$row['last_name'];
$userName = $row['username'];
}
}
if ($login='Y')
{
setcookie('name',$welcome,time()+60*60*24*30);
setcookie('login',"Y",time()+60*60*24*30);
$_SESSION['username_login'] = $userName;
header('Location: welcome.php');
}
Here is the modified code that I should of posted first I need it to check user entered password in this case $userPassword with the encrypted password if its a match it will send the user into the next page of the site.
You don't need to see the password in clear text ( you can't even if you wanted to). As you are checking the record both on password and username you don't need the check in your if() statement. If there is any row found, that means the username/password combination was succesfful and the user can be deemed as logged in.
Edit:
The updated code doesn't really make any difference to the actual logic. The logic stays the same, you query the database with username AND encrypted password, if there is a match that means the user has the right to login, so you proceed with setting the cookies/session data and redirect. Although I do not really see the need for the login cookie and the welcome cookie cause you could simply put in both username, fname and lname in the session. If the session on the following pages contains username that means the user has logged in.
The code can go something like this:
//sets $query to read usnername and passowd from table
$query = "SELECT username,first_name,last_name FROM jubreyLogin WHERE username = '$userName' AND password=password('$userPassword')";
$result = mysql_query($query,$db);
if(mysql_error())
{
echo $query;
echo mysql_error();
}
// were any rows returned?
if(mysql_num_rows($result)){
list($userName, $firstName , $lastName) = mysql_fetch_row($result);
$welcome = "Welcome" . " " .$firstName. " " .$lastName;
setcookie('name',$welcome,time()+60*60*24*30);
setcookie('login',"Y",time()+60*60*24*30);
$_SESSION['username_login'] = $userName;
header('Location: welcome.php');
}
You should not be encrypting your passwords, you should be hashing them. Try using a library such as phpass to be on the safe side. What you will need to do is hash the passwords and store the hashed value in the database. When a user logs in, you will hash the password they provide and compare that with the hashed value in the database. If the hashes match, the password provided is correct. If not, you send an error to the user. You never need to be able to obtain the password in plain text in order to validate a user.
Also, make sure that you are either escaping your variables using mysql_real_escape_string() or prepared statements or your script will be vulnerable to SQL injection.

How to improve login script?

How can I ensure my login script is secure and make it better, This is my first code:
Help is most appreciated.
<?php
include ('../includes/db_connect.php');
$firstname = $_POST['firstname'];
$lastname = $_POST['lastname'];
$email = $_POST['email'];
$mobile = $_POST['mobile'];
$username = $_POST['username'];
$password = md5($_POST['password']);
// lets check to see if the username already exists
$checkuser = mysql_query("SELECT username FROM users WHERE username='$username'");
$username_exist = mysql_num_rows($checkuser);
if($username_exist > 0){
echo "I'm sorry but the username you specified has already been taken. Please pick another one.";
unset($username);
header("Location: /registration?registration=false");
exit();
}
// lf no errors present with the username
// use a query to insert the data into the database.
$query = "INSERT INTO users (firstname, lastname, email, mobile, username, password)
VALUES('$firstname', '$lastname','$email', '$mobile','$username', '$password')";
mysql_query($query) or die(mysql_error());
mysql_close();
echo "You have successfully Registered";
header("Location: /registration?registration=true");
// mail user their information
//$yoursite = ‘www.blahblah.com’;
//$webmaster = ‘yourname’;
//$youremail = ‘youremail’;
//
//$subject = "You have successfully registered at $yoursite...";
//$message = "Dear $firstname, you are now registered at our web site.
// To login, simply go to our web page and enter in the following details in the login form:
// Username: $username
// Password: $password
//
// Please print this information out and store it for future reference.
//
// Thanks,
// $webmaster";
//
//mail($email, $subject, $message, "From: $yoursite <$youremail>\nX-Mailer:PHP/" . phpversion());
//
//echo "Your information has been mailed to your email address.";
?>
Follow Artefacto's advice about SQL injection and Hashing passwords in the database. Other things ...
echo "I'm sorry but the username you specified has already been taken. Please pick another one.";
unset($username);
header("Location: /registration?registration=false");
Wont work because you can't echo then send a header. Headers must be sent before any output.
Also, there is no point doing this:
header("Location: /registration?registration=false");
echo "I'm sorry but the username you specified has already been taken. Please pick another one.";
unset($username);
The webbrowser will redirect straight away and the user won't see the handy message you've printed.
Also, it's usual to ask for 2 password fields on registration forms incase the user made a typo and didn't notice because all the text was *'s. You compare the 2 and if they are different you assume a typo was made and ask again.
That's not a login script. It's a registration script.
See SQL injection in the PHP manual. Your program is vulnerable to this kind of attacks.
Also, don't just or die(mysql_error()). This will expose information about your database that you may not want to expose (table names, etc.). Use proper error handling. For instance, you can throw an exception and define a uncaught exception handler that shows a "oops" page and logs the error.
Finally, use hashes strong than MD5, such as sha1.
As said by #Artefacto, that's not a login script.
But if you intend to do a login script I would like to give you a suggestion. I've done this a while ago.
Instead of doing something like this:
$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
I would do this:
$sql = "SELECT * FROM users WHERE username = '$username'";
$user = //use the php-sql (query, fetch_row) commands to fetch the user row.
if (strcmp($user['password'], $password) == 0) {
//log in success
}
By doing this, you avoid SQL Injection in a simple and elegant way. What you guys think about it?
To reiterate what everyone else mentioned. It's important to protect yourself (and sever) from SQL injection. For example:
$checkuser = mysql_query("SELECT username FROM users WHERE username='$username'");
You're just simple taking the value from $_POST['username'] and placing it in the variable $username.
Some people aren't very nice and will try to break your program :( So it's always recommended to escape any data that was taken from a user, before placing it into an SQL query.
For instance...
This:
$checkuser = mysql_query("SELECT username FROM users WHERE username='$username'");
Becomes:
$checkuser = mysql_query("SELECT username FROM users WHERE username='" .mysql_real_escape_string($username). "'");

Categories