Logout doesn't stop access

I have a login php which checks student name and password against a database. If both are correct, the student can open the page. Seems to work OK, lets me open the page if name and pw are in the database.

I put a nice little logout button on the page:

<?php include $_SERVER['DOCUMENT_ROOT'] . '/includes/logout.inc.html.php';?>

That looks like this:

<form action="" method="post">
  <div>
    <input type="hidden" name="action" value="logout">
    <input type="hidden" name="goto" value="/">
    <input type="submit" value="Log out">
  </div>
</form>

It works, inasmuch as , it takes me back to the homepage. However, if I click on the page I was logged into again, it opens without going to the login page first.

Is this some setting in php.ini?? What must I do to actually be logged out?

The whole access file is this:

<?php

function userIsLoggedIn1()
{
  if (isset($_POST['action']) and $_POST['action'] == 'login')
  {
    if (!isset($_POST['name']) or $_POST['name'] == '' or
      !isset($_POST['password']) or $_POST['password'] == '')
    {
      $GLOBALS['loginError'] = 'Please fill in both fields';
      return FALSE;
    }

    $password = md5($_POST['password'] . 'allstudentsdb');

    if (databaseContainsStudent1($_POST['name'], $password))
    {
      session_start();
      $_SESSION['loggedIn'] = TRUE;
      $_SESSION['name'] = $_POST['name'];
      $_SESSION['password'] = $password;
      return TRUE;
    }
    else
    {
      session_start();
      unset($_SESSION['loggedIn']);
      unset($_SESSION['name']);
      unset($_SESSION['password']);
      $GLOBALS['loginError'] =
          'The specified name or password was incorrect.';
      return FALSE;
    }
  }

  if (isset($_POST['action']) and $_POST['action'] == 'logout')
  {
    session_start();
    unset($_SESSION['loggedIn']);
    unset($_SESSION['name']);
    unset($_SESSION['password']);
   header('Location: ' . $_POST['goto']);
    exit();
  }

  session_start();
  if (isset($_SESSION['loggedIn']))
  {
    return databaseContainsStudent1($_SESSION['name'], $_SESSION['password']);
  }
}

function databaseContainsStudent1($name, $password)
{
  include $_SERVER['DOCUMENT_ROOT'] . '/includes/studentdbReadfrom.inc.php';

  try
  {
    $sql = 'SELECT COUNT(*) FROM 19BE
        WHERE name = :name AND password = :password';
    $s = $pdo->prepare($sql);
    $s->bindValue(':name', $name);
    $s->bindValue(':password', $password);
    $s->execute();
  }
  catch (PDOException $e)
  {
    $error = 'Error searching for name.';
    include $_SERVER['DOCUMENT_ROOT'] . '/includes/error.html.php';
    exit();
  }

  $row = $s->fetch();

  if ($row[0] > 0)
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}

?>

Throw that script in file 13 as it is obsolete and not safe. At the very least you should be using password_verify

I simply have these two functions on my pages that I don’t regular users accessing.

confirm_user_logged_in();
is_session_valid();

I have this in my configuration file:

    // Should the session be considered valid?
    function is_session_valid() {
        $check_ip = true;
        $check_user_agent = true;
        $check_last_login = true;

        if ($check_ip && !request_ip_matches_session()) {
            return false;
        }
        if ($check_user_agent && !request_user_agent_matches_session()) {
            return false;
        }
        if ($check_last_login && !last_login_is_recent()) {
            return false;
        }
        return true;
    }


// If user is not logged in, end and redirect to login page.
function confirm_user_logged_in() {
    if (!is_logged_in()) {
        end_session();
        // Note that header redirection requires output buffering 
        // to be turned on or requires nothing has been output 
        // (not even whitespace).
        header("Location: login.php");
        exit;
    }
}

I redirect if session is valid myself, but you could write another function to do that automatically. I got tired of it redirecting to a page that I did not want to go as I change web pages a lot.

Well, thanks for that, but I’ve got to say I don’t understand it. I am no programmer, I can only get bits of code from books or the web and try and bend them to suit my purpose. Could you possibly be a bit more explicit?

In my case, security is not an issue, this is basically just a homework page.

Because of this virus here in China, our new term, which should begin on the 17th Feb. is postponed until the govt. decides it is safe. So my boss asked me to try and offer online classes for my students. I already do the same thing for homework: Listen to the mp3, fill in the gaps, choose multi-choice answers. PHP writes each student’s answers to a text file, I fetch them all with rsync and Python marks them. I’m planning writing them to mysql and marking them on the webpage, but that’s a bit complicated for me at the moment.

What I want to do is catch the login and use it as attendance, for each login add 1 to the attendance table.

But I still wonder why logout does not actually log out!

you need to clear the session.

session_destroy()

What code do you have on the ‘protected’ page(s) to prevent access to those page(s)?

It is not always desirable to destroy the whole session. To unset just one element you can do:

unset($_SESSION['my_var']);

True, but when you want to logout, it is probably best to destroy the entirety.

2 Likes

Please remember, this is all newland for me!

@phdr: my webpage starts with index.php At the bottom is:

include 'startfile.html.php';

The first thing you see is 6 buttons. If I click say 19BE1, that redirects to login. The student enters his or her name and password = student number. This is not really for security, there is only homework or now, online classwork there.

If the login succeeds, 19BE1/19BEleitfile.html opens, a list of buttons labelled Week 1 and so on. The student can proceed to class.

I use the login to check attendance. This is part of access19BE1.inc.php Strider64 said above, this code is obsolete, but it is all I have, and it works! If you have any suggestions for improvement, please let me know. I posted the whole access19BE1.inc.php above.

if (databaseContainsStudent1($_POST['name'], $password))
    {
      session_start();
      $_SESSION['loggedIn'] = TRUE;
      $_SESSION['name'] = $_POST['name'];
      $_SESSION['password'] = $password;
       	
    // my stuff THIS WORKS!!
 	
    include $_SERVER['DOCUMENT_ROOT'] . '/includes/studentdbReadfrom.inc.php' ;
	try
  {
	 // attendance will not increase with multiple logins. Before next week, reset has_been_incremented to zero  	
  	 $sql = 'UPDATE 19BEattendance SET attendance = attendance + 1, 
  	 has_been_incremented = has_been_incremented + 1, time = LOCALTIME() 
  	 WHERE number = ' . $_POST['password'] . ' AND has_been_incremented != 1 ;';
    $pdo->exec($sql);
      }
	catch (PDOException $e)
  {
    $error = 'Error searching for name.';
    include $_SERVER['DOCUMENT_ROOT'] . '/includes/error.html.php';
    exit();
  }
    
    // end my stuff	THIS WORKS
     
      return TRUE;
    }

This adds 1 to attendance and has_been_incremented and timestamps it. Once a week I will export this and put the attendance in my attendance sheet.

I put the logout button in the first page, startfile.html.php and I inserted the logout code in index.php.

if (isset($_POST['action']) and $_POST['action'] == 'logout')
  {
    session_start();
    unset($_SESSION['loggedIn']);
    unset($_SESSION['name']);
    unset($_SESSION['password']);
    //session_unset();     // unset $_SESSION variable for the run-time 
    //session_destroy();   // destroy session data in storage
    header('Location: ' . $_POST['goto']);
    exit();
  }

Now, when I click logout, I am logged out. Also, as I don’t really know what I’m doing, I keep /var/log/apache2/error.log open.

At the moment, I am not getting any errors, so this seems to be working!

However, I am extremely grateful for any tips from you experts, should you have any!

When you log new students, or log students in, use password_hash
https://www.php.net/manual/en/function.password-hash.php
This means you should make each student change their password and use the hash

To verify them when they log in, use password_verify
https://www.php.net/manual/en/function.password-verify.php
Never ever use MD5. That technology is from the 80’s and can be broken in minutes by a hacker.

They don’t actually have to change their password, you can implement it in the back to update the algorithm used; not that it is a bad idea to change the password anyway.

While I didnt want to do a tutorial on the hash, I thought it might be best if he rewrote the script, had others use it and verify their new passwords so he could learn to use the security. But you are right. There are probably many youtube videos on how to do it

Thanks for the tips and links, I will look them up! This is my first time using PHP and MySQL, bound to be problems!

Technology from the 80s? My book was published in 2012! Maybe that Kevin Yank is a hacker!!

Actually, I just use the login to check attendance. When they login, mysql ups their attendance 1 time. Until I reset the column has_been_incremented, it won’t up again. No sneaky 100% or 1000% attendance!

Thank God, security is really not a problem. Worst case scenario: they wipe out my page. I keep everything in /var/www where I try it out first. Upload.

My host is GoDaddy. I’m sure their security is quite good, even if their cPanel is iffy!

Sponsor our Newsletter | Privacy Policy | Terms of Service