Site authentication

I am building a very simple PHP/MySQL site that allows users to track their dreams and length of sleep. I have successfully made it works as far as inserting and displaying the data. My next step is to set up authentication and user DB. I want to achieve a few things in the simplest way possible:

  1. Allow users to create an account
  2. be able to authenticate a user
  3. present the user only their information

Does anyone have a rec on using a framework or resources for building from scratch? Which is the best way to go in this scenario?

I have checked out PEAR LiveUser and Auth, which seem great, but perhaps a bit too robust, i.e. I am having a hard time figuring out how to implement it with my noob-level of PHP.

Thanks

I recommend Kohana Framework 3.2. It comes with a quite powerful Auth module.
You can also try CodeIgniter, there are many different auth plugins available for it.

OK, if you don’t know how to do this, avoid frameworks for the time being, learn the basics first then either use an existing framework or code up your own. I’ve been discussing authentication and framework structures here: http://www.sitepoint.com/forums/showthread.php?824586-Managing-authentication-on-a-per-page-basis-Discussion so might be worth a quick read.

Anyway here is a dead simple method of implementing a registration system, code will be partial as I don’t know your current code structure, also I’m not going to care too much for security or standards, just a general process:

  1. Create a registration form containing
  • username (desired username)
  • password (desired password)
  • confirm password
  • email (your email address)
  • confirm email
  • Anything else you need (i.e. gender, date of birth)
  • CAPTCHA (google it)
  1. On submission, submit to a PHP script, we will assume this to either be register.php or sitename.com/register if your using an architecture like I describe in that thread I linked.

This script will do a number of things:

A. Include your application backend and the classes or function libraries used for registration.
B. Collect the user input
C: Validate the form fields
D: Check that the username is available and that the email is available
E: Create an account

You will in practice want email verification but this is easy

You should have either a class or function library with the following methods/functions:


public function createAccount()
{
   $username = $_POST['username'];
   $password = $_POST['password'];
   $password_confirm = $_POST['password_confirm'];
   $email = $_POST['email'];
   $email_confirm = $_POST['email_confirm'];


   $this->verifyUsername($username);
   $this->verifyPassword($password, $password_confirm);
   $this->verifyEmail($email, $email_confirm);

   $this->create_account($username, $email, $password);

   return 0;
}

Now, those POST collections, you’d want to use some kind of input cleaning here, mysql_real_escape_string or a more detailed custom built cleaner.
The variable sets I did locally and passed into the functions, in OO you would define them in the class space and do $this->username = $_POST[‘username’] so you don’t need to pass them around.

The function calls (methods) would simply do what they suggest, verify that the inputs are valid i.e. valid email, emails match, username and email aren’t already taken.

If you are using functional decomposition then the process would be similar, except you would have the public before the function and the $this-> would be removed from the function calls.

The createAccount function/method is important. I’ll do it all in the function but in practice you’d probably want to do stuff like the password encrypt in a separate function/method for re-usability.


createAccount($username, $email, $password)
{
   // First we need to create the password (encrypt it)

   // We first encrypt the password
   $password_hash = sha1($password);

   // Then we create a salt
   $joindate = time(); // Create a timestamp

   // Now generate the salt
   $salt_hash = sha1($joindate);
   $salt = substr($salt_hash,0,3);	// Take the first 3 characters of the salt hash	
		
   $formed_hash = $password_hash . $salt;
   
   // This is your final hash key for the password
   $final_hash = sha1($formed_hash);
   
   // Then insert it into the DB
   // You want to insert the final_hash var for the password, store the salt and the joindate as you'll need them to login.
   return 0;
}

You then have a login form with username, password and probably a remember me checkbox.

That form leads to your login script which will collect the form vars, validate them and then attempt to create a login.

You take the users password, lookup the user account and generate a password hash in the same way as you did on register (but using the stored joindate to create the salt) and compare the hash key you just generated from the login form with the hash key stored.

if they match, the password is a match, so you set a login cookie/create a session.

Then your application itself, that will check for a cookie/session, if the user has a cookie/session you validate the hash key in there with the login session/hash key on the account to set the user as a member of a guest.

Basically, something like that.

Setting a cookie and collecting a cookie is pretty easy:


// To collect a cookie
$cookie_value = $_COOKIE['cookie_name'];

// To set a cookie
setcookie("cookie_name", $value, $expire_time, "/", "", 0);

You would also have a method (probably in the core of your framework) which collects a cookie/checks for a session and validate it (kinda as I described above), if a login exists and its valid then you’d grab their account (the session or cookie would need to reference their userid so you know who’s account to collect).

like


$userid = $_COOKIE['userid'];
$hash = $_COOKIE['sessionhash'];

$auth->verifySession($userid, $hash);


If the verifySession is successful you’d set their usergroup to guest and if its valid to member (or whatever) and let your permissions handle the rest. In practice you might want to wipe out cookies/sessions if something is iffy about them (i.e. it returns invalid), maybe show a login screen or whatever else you need to do.

That verifySession method would interface with a user manager which would be what grabs the usergroup and account details.

I know thats all very fragmented and its far from perfect, but gives a general direction. Hopefully get you thinking about some kind of process :slight_smile:

Awesome! Thanks all for the detailed responses. I have some work ahead of me :slight_smile: