60

I'm pretty new to PHP and I am trying to figure out how to use sessions to check and see if a user is logged into a website so that they would have authorization to access specific pages.

Is this something that is complicated or is it because I am a noob that I can't figure it out?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Andrew
  • 629
  • 1
  • 7
  • 6
  • 7
    yeah but I was looking for someone to explain it in a fasion that I could understand so thanks! – Andrew Oct 09 '09 at 19:50

8 Answers8

118

Logins are not too complicated, but there are some specific pieces that almost all login processes need.

First, make sure you enable the session variable on all pages that require knowledge of logged-in status by putting this at the beginning of those pages:

session_start();

Next, when the user submits their username and password via the login form, you will typically check their username and password by querying a database containing username and password information, such as MySQL. If the database returns a match, you can then set a session variable to contain that fact. You might also want to include other information:

if (match_found_in_database()) {
    $_SESSION['loggedin'] = true;
    $_SESSION['username'] = $username; // $username coming from the form, such as $_POST['username']
                                       // something like this is optional, of course
}

Then, on the page that depends on logged-in status, put the following (don't forget the session_start()):

if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] == true) {
    echo "Welcome to the member's area, " . htmlspecialchars($_SESSION['username']) . "!";
} else {
    echo "Please log in first to see this page.";
}

Those are the basic components. If you need help with the SQL aspect, there are tutorials-a-plenty around the net.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
Ben Torell
  • 2,053
  • 1
  • 12
  • 15
  • 2
    thanks for explaining this. i was wonder if it possible to make a folder restricted instead of a page? so any page that i have in that folder is restricted unless you are logged in? – CodeMonkey May 16 '15 at 07:50
30

Almost all of the answers on this page rely on checking a session variable's existence to validate a user login. That is absolutely fine, but it is important to consider that the PHP session state is not unique to your application if there are multiple virtual hosts/sites on the same bare metal.

If you have two PHP applications on a webserver, both checking a user's login status with a boolean flag in a session variable called 'isLoggedIn', then a user could log into one of the applications and then automagically gain access to the second without credentials.

I suspect even the most dinosaur of commercial shared hosting wouldn't let virtual hosts share the same PHP environment in such a way that this could happen across multiple customers site's (anymore), but its something to consider in your own environments.

The very simple solution is to use a session variable that identifies the app rather than a boolean flag. e.g $SESSION["isLoggedInToExample.com"].

Source: I'm a penetration tester, with a lot of experience on how you shouldn't do stuff.

hiburn8
  • 473
  • 5
  • 12
  • This is a valid point. In most use-cases your'e storing session login boolean flag with an additional Session variable such as a user token which can be used to validate the user entirely before providing access. But as stated before $SESSION["isLoggedInToExample.com"] is a better approach than $SESSION["loggedIn"] but I would hope a unique field is also being validated before giving access. – Jeacovy Gayle Mar 15 '19 at 14:09
  • I think the above is probably enough to validate access to a site, since it comes from a cookie... insinuating some sort of forms-based authentication has already occurred. Beyond that you can still perform additional checks for a more granular levels of user access-control; depending on the type of site you run. – hiburn8 Mar 15 '19 at 16:09
  • 2
    How secure is the session information? I understand that it's stored in a `tmp` directory on the server. Could an attacker modify the session data to log themselves in? Is that something I should concern myself with? Also, should I avoid storing encryption keys in the session? – Indiana Kernick Oct 12 '20 at 11:45
  • I think you're asking a new question there @IndianaKernick. The session data is secure in that its not in the web root. But its probably never a suitable place for encryption keys. You want a database with proper access controls for anything sensitive. Even using session storage to cache user data is risky if its PII. You're usually just better off going back to the database or finding alternate solutions. – hiburn8 Nov 12 '20 at 10:24
12

Any page you want to perform session-checks on needs to start with:

session_start();

From there, you check your session array for a variable indicating they are logged in:

if (!$_SESSION["loggedIn"]) {
    redirect_to_login();
    die;
}

Logging them in is nothing more than setting that value:

$_SESSION["loggedIn"] = true;
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
Sampson
  • 265,109
  • 74
  • 539
  • 565
1

You need this on all pages before you check for current sessions:

session_start();

Check if $_SESSION["loggedIn"] (is not) true - If not, redirect them to the login page.

if($_SESSION["loggedIn"] != true){
    echo 'not logged in';
    header("Location: login.php");
    exit;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jeacovy Gayle
  • 447
  • 9
  • 9
0

You may do a session and place it:

// Start session
session_start();

// Check do the person logged in
if($_SESSION['username']==NULL){
    // Haven't log in
    echo "You haven't log in";
}else{
    // Logged in
    echo "Successfully logged in!";
}

Note: you must make a form which contain $_SESSION['username'] = $login_input_username;

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0

Apart from the splendid answer von @hiburn8 what is missing is a secure why to logoff / logout. I realize this was not asked but should be considered as well.

Loging off should contain two elements:

  1. remove all data from the session variable
  2. reset the ID to prevent from session reuse attempts.

Perhaps 2) is not needed if all session data was destroyed but there might be (future) scenarios where this might be a good thing. Luckily PHP offers a function for both the elements and a complete code would be:

session_start();             // get a session to manipulate
session_unset();             // remove all server data on the session
session_regenerate_id(true); // create a new session id to prevent hijacking

This should typically go in a logoff script.

theking2
  • 2,174
  • 1
  • 27
  • 36
  • Incidentally, this answer *directly contradicts* with the splendid answer von @hiburn8, which explicitly states that a session may contain other data, beside login information for a particular site. And so it must be handled specifically, instead of destroying the entire session – Your Common Sense May 18 '22 at 13:09
-3

See this script for registering. It is simple and very easy to understand.

<?php
    define('DB_HOST', 'Your Host[Could be localhost or also a website]');
    define('DB_NAME', 'database name');
    define('DB_USERNAME', 'Username[In many cases root, but some sites offer a MySQL page where the username might be different]');
    define('DB_PASSWORD', 'whatever you keep[if username is root then 99% of the password is blank]');

    $link = mysql_connect(DB_HOST, DB_USERNAME, DB_PASSWORD);

    if (!$link) {
        die('Could not connect line 9');
    }

    $DB_SELECT = mysql_select_db(DB_NAME, $link);

    if (!$DB_SELECT) {
        die('Could not connect line 15');
    }

    $valueone = $_POST['name'];
    $valuetwo = $_POST['last_name'];
    $valuethree = $_POST['email'];
    $valuefour = $_POST['password'];
    $valuefive = $_POST['age'];

    $sqlone = "INSERT INTO user (name, last_name, email, password, age) VALUES ('$valueone','$valuetwo','$valuethree','$valuefour','$valuefive')";

    if (!mysql_query($sqlone)) {
        die('Could not connect name line 33');
    }

    mysql_close();
?>

Make sure you make all the database stuff using phpMyAdmin. It's a very easy tool to work with. You can find it here: phpMyAdmin

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user3627194
  • 9
  • 2
  • 8
  • 2
    Not only does this not answer the original question, but it's also a poor example. The script is open to SQL Injection, and from a personal point of view, I wouldn't recommend phpmyadmin to anyone. – Chris J Jan 12 '19 at 15:34
  • I can only concur @ChrisJ apart from that there are no checks on the $_POST entries set. Even after replacing `mysql` with `mysqli` it is an ok example in a dev/test environment but in production it is poor code. __do not use!__ – theking2 May 18 '22 at 10:02
-5
else if (isset($_GET['actie']) && $_GET['actie']== "aanmelden"){

    $username= $_POST['username'];
    $password= md5($_POST['password']);
    $query = "SELECT password FROM tbl WHERE username = '$username'";
    $result= mysql_query($query);
    $row= mysql_fetch_array($result);

    if($password == $row['password']){
            session_start();
            $_SESSION['logged in'] = true;
            echo "Logged in";

    }
}
moriarty5
  • 1
  • 2
  • 1
    This code is vulnerable to SQL Injection, you should not be storing passwords as MD5 hashes in 2019, it uses deprecated PHP functions, and comes with zero explanation. This is an AWFUL answer and should be removed. – hiburn8 Jan 14 '19 at 17:42
  • 1
    Also, since there is no error-checking... it might be possible to force the $row and $password values to FALSE and therefore bypass the login. I just checked and md5() has a return value of FALSE on failure... so sending the password value as an array rather than a string would bypass it. – hiburn8 Jan 14 '19 at 17:56
  • 1
    Even as a blueprint, this makes my blood boil. That session_start() is only called if the password is correct. So what about people who are logged in, but somehow end up trying to log in again with the wrong credentials?... do they get kicked on the next response, but then if they navigate to another page they are magically logged in again? The session_start() should live elsewhere. – hiburn8 Jan 14 '19 at 17:57
  • 1
    I could write a book about why i hate this answer. – hiburn8 Jan 14 '19 at 17:57