phpsessionlogin-scriptaccess-levels

How can I add user/access levels to my current login script?


I'm currently learning PHP and MySQL and I have been working from a basic (albeit old) login script tutorial - I've come across various depreciated functions and such and I'm trying to improve on this script.

I would like to add different access levels to my script such as admins and users. I have added a row in my 'users' table called 'access' whereby access will be be '1' for users and '9' for admins.

After some initial research it seems I need to be able to store the users access level in a session variable - is this the right way to go about it? If so, how would I retrieve this initially, when the user logs in?

Once the access level is stored in the session variable, how will I then be able restrict access to pages - using header redirects perhaps?

This is the current code I'm working with from functions.php

function checkLogin()
    {
    /* Check if user has been remembered */
    if(isset($_COOKIE['cookname']) && isset($_COOKIE['cookpass'])){
        $_SESSION['username'] = $_COOKIE['cookname'];
        $_SESSION['password'] = $_COOKIE['cookpass'];
    }

    /* Username and password have been set */
    if(isset($_SESSION['username']) && isset($_SESSION['password']))
    {
    /* Confirm that username and password are valid */
    if(confirmUser($_SESSION['username'], $_SESSION['password']) != 0)
    {
    /* Variables are incorrect, user not logged in */
        unset($_SESSION['username']);
        unset($_SESSION['password']);
        return false;
    }
        return true;
    }
    /* User not logged in */
    else
    {
      return false;
    }
    }

And from login.php

if(isset($_POST['sublogin'])){
   /* Check that all fields were typed in */
   if(!$_POST['user'] || !$_POST['pass']){
      $errors .= "You didn't fill in a required field.<br/>\n";

   }


else{

    /* Once all fields are entered - perform form validation */


   /* Checks that username is in database and password is correct */
   $md5pass = md5($_POST['pass']);
   $result = confirmUser($_POST['user'], $md5pass);

   /* Check error codes */
   if($result == 1){
      $user_errors .= "That username doesn't exist in our database.<br/>\n";
   }
   else if($result == 2){
      $pass_errors .= "Incorrect password, please try again.<br/>\n";
   }


   /* Username and password correct, register session variables */
   if (empty($errors) && empty($user_errors) && empty($pass_errors)){
        $_POST['user'] = mysql_real_escape_string($_POST['user']);
        $_SESSION['username'] = $_POST['user'];
        $_SESSION['password'] = $md5pass;
        /* Quick self-redirect to avoid resending data on refresh */
        echo "<META HTTP-EQUIV='refresh' CONTENT='0;URL=index.php'>";
   } 



   /**
    * This is the cool part: the user has requested that we remember that
    * and one to hold his md5 encrypted password. We set them both to
    * he's logged in, so we set two cookies. One to hold his username,
    * expire in 100 days. Now, next time he comes to our site, we will
    * log him in automatically.
    */
   if(isset($_POST['remember'])){
      setcookie("cookname", $_SESSION['username'], time()+60*60*24*100, "/");
      setcookie("cookpass", $_SESSION['password'], time()+60*60*24*100, "/");
    }

    //return;
}
}

Any help would be really appreciated as I've been stuck on this for a few days now, thanks.


Solution

  • So this ex assumes that you are checking the limiting resources to roles in your PHP not from the DB. This can be easily changed, but i figured i'd make this ex a little simple.

    Schema:

    users
    -------
    id_user
    identity
    credential
    role
    ... other fields
    

    Account Creation

    don't use md5, its easy to implement, and easily overcome. sha is just a litttle more secure with no additional work.

    $email_or_username = "francis@yaconiello.com";
    $password = "PinkEleph4nt"; // not my real password for anything
    $role = "admin";
    $sql = sprintf("INSERT INTO users SET identity='%s', credential='%s', role='%s'",
        mysql_real_escape_string($email_or_username), 
        mysql_real_escape_string(sha1($password)), 
        mysql_real_escape_string($role));
    

    Account Login

    This is shortened, i threw the query in, but not alot of the DB logic, write it as its needed, read the comments.

    // VALIDATE THE EMAIL/USERNAME and PASSWORD
    
    if($is_valid == TRUE)
    {
        $sql = sprintf("SELECT id_user FROM users WHERE identity='%s' AND credential='%s' LIMIT 1",
            mysql_real_escape_string($email_or_username), 
            mysql_real_escape_string(sha1($password)));
    
        // FETCH ROW save into $row
    
        if(!empty($row))
        {
            // A user was fetched save it into the session
            $_SESSION['id_user'] = $row['id_user'];
    
            // SUCCESS
        }
        else
        {
            // FAILURE
        }
    }
    

    Check user's role

    <?php
    function fetch_role()
    {
        $role = "guest";
        if(isset($_SESSION['id_user']))
        {
            // User exists
            $sql = sprintf("SELECT * FROM users WHERE id_user='%s' LIMIT 1",
                mysql_real_escape_string($_SESSION['id_user']));
    
            // RUN THE MYSQL QUERY TO FETCH THE USER, SAVE INTO $row
    
            if(!empty($row))
            {
                $role = $user_row['role'];
            }
        }
    
        return $role;
    }
    
    ...
    
    $role = fetch_role();
    if($role == 'guest')
    {
        // SHOW GUEST CONTENT
    }
    elseif($role == 'member')
    {
        // SHOW OTHER CONTENT
    }
    elseif($role == 'admin')
    {
        // SHOW ADMIN CONTENT
    }