Basic user accounts with PHP and MySQL

This is a tutorial on adding basic user accounts to your site.

Objective:
  1. Create a registration and sign in page.
  2. Require users to log in to view designated pages.
Target Audience:
  1. Someone with basic MySQL and PHP knowledge.
  2. Someone who wants user accounts without using a framework like Joomla or CakePHP.

First, let's create the 'users' mysql table.

CREATE TABLE `users` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(20) NOT NULL,
`password_hash` varchar(40) NOT NULL,
`password_salt` varchar(8) NOT NULL,
`created` datetime default NULL,
PRIMARY KEY  (`id`)
);

To add some security to the site, I'm encrypting the passwords (hence the password_salt and password_hash fields). This stops anyone from knowing a password by looking in the database.

Next, we'll make the sign up form (signup.php). This is where users will register for your site.

<html>
<head>
<title>Sign Up</title>
</head>
<?php
if(isset($_REQUEST['username'])) //Form submitted
{
 //Connect to database
 $conn = mysql_connect('localhost', 'root', 'password') 
  or die('Could not connect: ' . mysql_error());
 mysql_select_db('database_name');

 //Sanitize entered info
 $username = mysql_real_escape_string($_REQUEST['username']);
 $password = mysql_real_escape_string($_REQUEST['password']);
 
 //Validate entered info
 $test = true;
 if(empty($username) || empty($password))
  $test = false;

 if($test) //Validation passed
 {
  //Generate random 8 character password salt
  $password_salt = "";

  //characters to choose from
  $chars = "0123456789abcdefghijklmnopqrstuvwxyz-_%#"; 
  for($C=0;$C<8;$C++)
  {
   $password_salt .= $chars{rand(0,strlen($chars)-1)};
  }
  
  //Generate hash based on entered password and salt
  $password_hash = md5($password_salt.$password);

  //Insert user in database
  $query = "INSERT INTO users 
    (username,password_salt,password_hash,created) VALUES 
    ('$username','$password_salt','$password_hash',NOW())";
  mysql_query($query) or 
    die ("Error creating new user: " . mysql_error());

  //Display success message and exit
  exit(
    "Account created successfully.  You may now 
    <a href='signin.php'>Sign In</a>"
  );
 }
 else //Validation failed
  echo "Please enter all information";
?>
<h1>Sign Up</h1>
<form action="signup.php" method="post">
Username: 
<input type="text" name="username" /><br />
Password: 
<input type="password" name="password" /><br />
<input type="submit" value="Sign Up" />
</form>
</body>
</html>

Make sure to change the mysql connection settings above to match your configuration.

Lastly, we'll make the sign in page (signin.php). If a user tries to access a restricted page, they will be redirected here.

<?php
session_start(); //Start session so we can sign user in
?>
<html>
<head>
<title>Sign In</title>
</head>
<?php
if(isset($_REQUEST['username'])) //Form submitted
{
 //Connect to database
 $conn = mysql_connect('localhost', 'root', 'password') 
  or die('Could not connect: ' . mysql_error());
 mysql_select_db('database_name');

 //Sanitize entered info
 $username = mysql_real_escape_string($_REQUEST['username']);
 $password = mysql_real_escape_string($_REQUEST['password']);
 
 //Select users with enetered username from database
 $query = "
    SELECT id,username,password_salt,password_hash 
    FROM users 
    WHERE username='$username'";
 $result = mysql_query($query) 
    or die("Error looking up user: " . mysql_error());
 
 
 if($row=mysql_fetch_assoc($result))//Row is returned
 {
  //Generate hash based on entered password and stored salt
  $password_hash = md5($row['password_salt'].$password);
  
  //If User entered correct password
  if($password_hash == $row['password_hash'])
  {
   //Sign them in by storing their id in a session variable
   $_SESSION['userid']=$row['id'];
   
   //Show message and exit
   exit( "You are successfully signed in." );
  }
  else //Incorrect password
  {
   echo "Incorrect Password";
  }
 }
 else //Incorrect Username
 {
  echo "Incorrect Username";
 }
}
//Show sign in form
?>
<h1>Sign In</h1>
<form action="signin.php" method="post">
Username: 
<input type="text" name="username" /><br />
Password: 
<input type="password" name="password" /><br />
<input type="submit" value="Sign In" />
</form>
</body>
</html>

Again, make sure you change the mysql settings.

Now that people can sign up and sign in, you need a way to require this. Put this at the top of a page to require the user to sign in:

<?php
session_start();//Start the session
if(!isset($_SESSION['userid']))//User not signed in
{
 header("Location: signin.php");//Redirect to sign in page
 exit();//Stop script from executing
}
?>

Here are a few things to keep in mind:

  • "session_start();" must be the first line in a file. If there are any characters or whitespace before the opening php tag, it will not work.
  • This post is meant to explain how something works, not the best way to implement it. There are many improvements to be made and I may address them in the future.

0 comments: