title: PHP User Authentication
body: <p>I've been teaching myself PHP out of a couple of books, from the W3Schools site and using a whole bunch of posts of Stack Overflow.</p>
  
  <p>To try and put something into practice I'm trying to make a small image gallery that implements a user authentication system. Users have a security access that determines wether they have read, read write access or can administrate other users etc. I've only gotten as far as the login and add user stuff.</p>
  
  <p>I've modelled it off my work, where everyone has a unique employee ID and 8 digit email ID.</p>
  
  <p>I know this is a long shot, but I'm just wondering if anyone would be able to take a look and tell me if my code is heading down the right track? It's so different putting something 'real world' like this together from the basic examples provided in books. Any comments and suggestions would be appreciated....</p>
  
  <p><strong>login.php</strong></p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;?php       
     // Connect to the database
     include('./helpers/db.php');
     include('./helpers/general.php');
  
     // Check if the user has submitted their details.
     if ($_SERVER['REQUEST_METHOD'] == 'POST') {
         $loginId = htmlspecialchars(($_POST['userId']));
         $loginPass = htmlspecialchars(sha1($_POST['password']));
  
         // Check if they've submitted blank details.
         if (!checkLoginId($loginId) || (!checkPassword($_POST['password']))) {
             $errorMsg = "Please enter a valid username or password!";
         }
  
         else {
         // Select the details we want for the session info.
         $stmt = $dbh-&gt;prepare("SELECT firstName, lastName, securityLevel FROM 
                              userDetails WHERE registeredNumber = :loginId 
                              AND password = :loginPass" );
         $stmt-&gt;bindParam(':loginId', $loginId);
         $stmt-&gt;bindParam(':loginPass', $loginPass);
         $stmt-&gt;execute();
  
              // Make sure the user is found, and that there security level is 1 or more.
              if ($stmt-&gt;rowCount() &gt; 0) {
                  $userDetails = $stmt-&gt;fetch();
  
                  if ($userDetails['securityLevel'] &lt; 1) {
                      $errorMsg = "Insufficient access for this user.";
                  }
  
                  else {
  
                  // Start a new session and set up the regularly used info.
                  session_start();
                  $_SESSION['loggedIn'] = 1;
                  $_SESSION['userID'] = $loginId;
                  $_SESSION['fname'] = $userDetails['firstName'];
                  $_SESSION['lname'] = $userDetails['lastName'];
                  $_SESSION['security'] = $userDetails['securityLevel'];
                  header("Location: ./browser/");
                  }
              }
  
              else {
                  $errorMsg = "Invalid User ID or Password!";
              }
         }
     }
  ?&gt;
  
  &lt;html&gt;
  &lt;head&gt;
      &lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;
      &lt;title&gt;&lt;/title&gt;
  &lt;/head&gt;
  &lt;style type="text/css"&gt;
         body {font-family:sans-serif;}
         .warning {color:red;font-weight:bold;}
         #login {margin-left:auto;margin-right:auto;width:200px;border-style:solid;border-width:1px;padding:20px;}
  &lt;/style&gt;
  &lt;body&gt;
     &lt;!-- Display the login form --&gt;
      &lt;div id="login"&gt;
          &lt;form action="login.php" method="POST"&gt;
          &lt;?php 
          if (isset($errorMsg)) {
              echo '&lt;span class="warning"&gt;'. $errorMsg . '&lt;/span&gt;';
          } 
          ?&gt;
          &lt;p&gt;&lt;label for="userId"&gt;User Name:&lt;/label&gt;&lt;br /&gt;
              &lt;input type="text" maxlength="5" name="userId"
                title="Enter your User ID:"&gt;
          &lt;/p&gt;
          &lt;p&gt;&lt;label for="pasword"&gt;Password:&lt;/label&gt;&lt;br/&gt;
              &lt;input type="password" maxlength="12" name="password"
                title="Enter your password:"/&gt;
          &lt;/p&gt;
          &lt;p&gt;&lt;input id="submit" type="submit" name="submit" value="Submit"&gt;&lt;/p&gt;
          &lt;/form&gt;
      &lt;/div&gt;
  &lt;/body&gt;
  </code></pre>
  
  <p></p>
  
  <p><strong>db.php</strong></p>
  
  <pre><code>&lt;?php
  $hostname = 'localhost';
  $dbname = 'dam';
  $dbuser = 'root';
  $dbpass = '****';
  
  // Try and connect to the database and catch the error if it doesn't work.
  
  try 
  {
      $dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $dbuser, $dbpass);
      echo "Connected to Database&lt;br/&gt;";
  }
  
  catch (PDOException $e) 
  {
      print "Error! " . $e-&gt;getMessage() . '&lt;br/&gt;';
      die();
  }
  
  ?&gt;
  </code></pre>
  
  <p><strong>general.php</strong></p>
  
  <pre><code>&lt;?php
  
  // Checks wether the loginID/Registered Number is valid
  function checkLoginId($login) {
  if ($login == '' || $login == NULL || (!is_numeric($login))) {
      return 0;
  }
  
  else return 1;
  }
  
  // Checks whether the password is valid
  function checkPassword($password) {
  if ($password == '' || $password == NULL) {
      return 0;
  }
  
  else return 1;
  }
  
  function verifyNewUser($userID, $upass, $fname, $lname, $email) {
  $hasErrors = 0;
  $errorMsg = array();
  
  if ($userID == '' || $userID == NULL || (!is_numeric($userID)) || (strlen($userID) != 5)) {
      $hasErrors++;
      $errorMsg[] = "User ID is either missing, or does not have 5 digits";
  }
  
  if ($upass == '' || $upass == NULL || (strlen($upass) &lt;  6)) {
      $hasErrors++;
      $errorMsg[] = "Password is either missing, or does not meet minimum length of six";
  }
  
  if ($fname == '' || $fname == NULL || empty($fname)) {
      $hasErrors++;
      $errorMsg[] = "First name is missing.";
  }
  
  if ($lname == '' || $lname == NULL || empty($lname)) {
      $hasErrors++;
      $errorMsg[] = "Last name is missing.";
  }
  
  if ($email == '' || $email == NULL || empty($email) || (strlen($email) != 8)) {
      $hasErrors++;
      $errorMsg[] = "Check email id, should be 8 characters.";
  }
  
  if ($hasErrors == 0) {
      return 1;
  
  }
  
  else {
      echo "Returning with errors&lt;br/&gt;";
      return $errorMsg;
      } 
  }
  ?&gt;
  </code></pre>
  
  <p><strong>adduser.php</strong>
      
  
  <pre><code>include ("./helpers/general.php");
  include('./helpers/db.php');
  
  session_start();
  
  // If the user isn't logged in, send them away...
  if (!(isset($_SESSION['loggedIn']) &amp;&amp; $_SESSION['loggedIn'] != '')) {
  header("Location: ./login.php");
  exit();
  }
  
  // Get the users full name so we can politely tell them to rack off if they 
  // don't have sufficient access to add users.
  $uname = $_SESSION['fname'] . ' ' . $_SESSION['lname'];
  
  // Check if the user has the security clearence to add a new user:
  if ($_SESSION['security'] != 4) {
  echo "Sorry $uname, only level 4 administrators can manage users.&lt;br/&gt;";
  echo '&lt;a href="./browser/"&gt;Back to Browser&lt;/a&gt;';
  exit();
  }
  
  // Check if they have submitted the form and validate the input
  if ($_SERVER['REQUEST_METHOD'] == 'POST') {
  
  $userID = htmlspecialchars($_POST['registeredNumber']);
  $upass = htmlspecialchars($_POST['password']);
  $fname = ucfirst(htmlspecialchars($_POST['firstName']));
  $lname = ucfirst(htmlspecialchars($_POST['lastName']));
  $email = htmlspecialchars($_POST['emailID']);
  $secLev = $_POST['securityLevel'];
  $creator = $_SESSION['userID'];
  
  $valid = verifyNewUser($userID, $upass, $fname, $lname, $email);
  
  if ($valid == 1) {
      // Encrypt the password
      $upass = sha1($upass);
  
      // Create the array to feed the SQL statement.
      $data = array($userID, $upass, $fname, $lname, $email, $secLev, date('Y-m-d H:i:s'), $creator);
  
      $dbh-&gt;beginTransaction();
      $stmt = $dbh-&gt;prepare("INSERT INTO userDetails VALUES('', ?, ?, ?, ?, ?, ?, ?, ?)");
      $stmt-&gt;execute($data);
      $dbh-&gt;commit();
  
      if ($stmt-&gt;rowCount() &gt; 0) {
          echo "Success, new user $fname $lname added!&lt;br/&gt;";
          echo "Email ID: $email&lt;br/&gt;";
          echo "Security Level: $secLev&lt;br/&gt;";
      }
  }    
  
  else if (isset($valid)) {
      foreach($valid as $error) {
          echo '&lt;span style="color:red;font-weight:bold"&gt;' . $error . "&lt;span&gt;&lt;br/&gt;";
      }
  }
  }
  
  ?&gt;
  
  &lt;!DOCTYPE html&gt;
  &lt;html&gt;
  &lt;head&gt;
      &lt;title&gt;Add A New User&lt;/title&gt;
      &lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;
  &lt;/head&gt;
  &lt;body&gt;
      &lt;form action="adduser.php" method="post"&gt;
      &lt;table&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;label for="registeredNumber"&gt;Registered Number:&lt;/label&gt;&lt;/td&gt;
              &lt;td&gt;&lt;input type="text" maxlength="5" name="registeredNumber"/&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;label for="password"&gt;Password:&lt;/label&gt;&lt;/td&gt;
              &lt;td&gt;&lt;input type="password" maxlength="12" name="password"/&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;label for="firstName"&gt;First Name:&lt;/label&gt;&lt;/td&gt;
              &lt;td&gt;&lt;input type="text" maxlength="20" name="firstName"/&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;label for="lastName"&gt;Last Name:&lt;/label&gt;&lt;/td&gt;
              &lt;td&gt;&lt;input type="text" maxlength="20" name="lastName"/&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;label for="emailID"&gt;Email ID:&lt;/label&gt;&lt;/td&gt;
              &lt;td&gt;&lt;input type="text" maxlength="8" name="emailID"/&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;label for="securityLevel"&gt;Security Level:&lt;/label&gt;&lt;/td&gt;
              &lt;td&gt;
                  &lt;select name="securityLevel"&gt;
                      &lt;option value="0" selected="selected"&gt;0 - No Access&lt;/option&gt;
                      &lt;option value="1"&gt;1 - Read Access&lt;/option&gt;
                      &lt;option value="2"&gt;2 - Read/Write Access&lt;/option&gt;
                      &lt;option value="3"&gt;3 - Read/Write/Delete Access&lt;/option&gt;
                      &lt;option value="4"&gt;4 - User Administrator&lt;/option&gt;
                  &lt;/select&gt;
              &lt;/td&gt;
          &lt;/tr&gt;
      &lt;/table&gt;
      &lt;input type="submit" name="submit" value="Submit"/&gt;
      &lt;/form&gt;
  &lt;/body&gt;
   &lt;/html&gt;
  </code></pre>
  
  <p><strong>logout.php</strong></p>
  
  <pre><code>&lt;?php
  
  // Destroy the session and go to the login screen.
  session_start();
  session_destroy();
  header("Location: login.php");
  ?&gt;
  </code></pre>