I want to create a simple login system where the user logs in, then it will keeps the details of user logged in stored and they will always be logged in until they have either clicked on the log out link. Now I heard that is better to user cookies in order to do this. Below is the login page:
teacherlogin.php script:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?php
// connect to the database
include('connect.php');
include('member.php');
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
die();
}
// required variables (make them explciit no need for foreach loop)
$teacherusername = (isset($_POST['teacherusername'])) ? $_POST['teacherusername'] : '';
$teacherpassword = (isset($_POST['teacherpassword'])) ? $_POST['teacherpassword'] : '';
$loggedIn = false;
$active = true;
if ((isset($username)) && (isset($userid))){
echo "You are already Logged In: <b>{$_SESSION['teacherforename']} {$_SESSION['teachersurname']}</b> | <a href='./menu.php'>Go to Menu</a> | <a href='./teacherlogout.php'>Logout</a>";
}
else{
if (isset($_POST['submit'])) {
$teacherpassword = md5(md5("g3f".$teacherpassword."rt4"));
// don't use $mysqli->prepare here
$query = "SELECT TeacherId, TeacherForename, TeacherSurname, TeacherUsername, TeacherPassword, Active FROM Teacher WHERE TeacherUsername = ? AND TeacherPassword = ? LIMIT 1";
// prepare query
$stmt=$mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("ss",$teacherusername,$teacherpassword);
// execute query
$stmt->execute();
// get result and assign variables (prefix with db)
$stmt->bind_result($dbTeacherId, $dbTeacherForename,$dbTeacherSurname,$dbTeacherUsername,$dbTeacherPassword, $dbActive);
while($stmt->fetch()) {
if ($teacherusername == $dbTeacherUsername && $teacherpassword == $dbTeacherPassword) {
if ($dbActive == 0) {
$loggedIn = false;
$active = false;
echo "You Must Activate Your Account from Email to Login";
}else {
$loggedIn = true;
$active = true;
$_SESSION['teacherid'] = $dbTeacherId;
$_SESSION['teacherusername'] = $dbTeacherUsername;
}
}
}
if ($loggedIn == true){
$_SESSION['teacherforename'] = $dbTeacherForename;
$_SESSION['teachersurname'] = $dbTeacherSurname;
header( 'Location: menu.php' ) ;
die();
}
if (!$loggedIn && $active && isset($_POST)) {
echo "<span style='color: red'>The Username or Password that you Entered is not Valid. Try Entering it Again</span>";
}
/* close statement */
$stmt->close();
/* close connection */
$mysqli->close();
}
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Teacher Login</title>
<link rel="stylesheet" type="text/css" href="TeacherLoginStyle.css">
</head>
<body>
<?php
include('noscript.php');
?>
<h1>TEACHER LOGIN</h1>
<form action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="post" id="teachLoginForm">
<p>Username</p><p><input type="text" name="teacherusername" /></p> <!-- Enter Teacher Username-->
<p>Password</p><p><input type="password" name="teacherpassword" /></p> <!-- Enter Teacher Password-->
<p><input id="loginSubmit" type="submit" value="Login" name="submit" /></p>
</form>
<a href="./forgotpass.php">Forgot Password</a>
</body>
<?php
}
?>
In the code above the user will enter in their username and password in the relevant text inputs. When they submit their login details, it will check in the database to see if their login details match in the database.
Now what I want to do is store the details of user’s username and id in a php script (member.php) so that it knows which user is logged in. But at the moment I am using $SESSION to do this which contains short amount of time:
member.php page:
<?php
if (isset($_SESSION['teacherid'])) {
$userid = $_SESSION['teacherid'];
}
if (isset($_SESSION['teacherusername'])) {
$username = $_SESSION['teacherusername'];
}
?>
How can I change the code above to get cookies involved so that the user’s details in the member page will stay for an unlimited time (until they log out of course).
UPDATE:
OK here is the Teacher Table in the database:
TeacherId (auto PK) TeacherForename TeacherSurname TeacherUsername, TeacherPassword
1 John Parks j.parks b018460fba79b
2 Mary Little u0876555 a33rfe3tn12e3
3 Jim Owen owensjimmy fkof04r3fk422
So are you saying first of all add a column SessionId into table above and store in a complex id for each user e.g. 34dekfm45345.
Then I will really need your help in order to be able to see the code on how to find the correct SessionId and delete the SessionId.
UPDATE 2:
So if I understand correctly, below is what the php scripts should look like:
teacherlogin.php:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?php
// connect to the database
include('connect.php');
include('member.php');
include('sessionuser.php');
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
die();
}
// required variables (make them explciit no need for foreach loop)
$teacherusername = (isset($_POST['teacherusername'])) ? $_POST['teacherusername'] : '';
$teacherpassword = (isset($_POST['teacherpassword'])) ? $_POST['teacherpassword'] : '';
$loggedIn = false;
$active = true;
if ((isset($username)) && (isset($userid))){
echo "You are already Logged In: <b>{$_SESSION['teacherforename']} {$_SESSION['teachersurname']}</b> | <a href='./menu.php'>Go to Menu</a> | <a href='./teacherlogout.php'>Logout</a>";
}
else{
if (isset($_POST['submit'])) {
$teacherpassword = md5(md5("g3f".$teacherpassword."rt4"));
// don't use $mysqli->prepare here
$query = "SELECT TeacherId, TeacherForename, TeacherSurname, TeacherUsername, TeacherPassword, Active FROM Teacher WHERE TeacherUsername = ? AND TeacherPassword = ? LIMIT 1";
// prepare query
$stmt=$mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("ss",$teacherusername,$teacherpassword);
// execute query
$stmt->execute();
// get result and assign variables (prefix with db)
$stmt->bind_result($dbTeacherId, $dbTeacherForename,$dbTeacherSurname,$dbTeacherUsername,$dbTeacherPassword, $dbActive);
while($stmt->fetch()) {
if ($teacherusername == $dbTeacherUsername && $teacherpassword == $dbTeacherPassword) {
if ($dbActive == 0) {
$loggedIn = false;
$active = false;
echo "You Must Activate Your Account from Email to Login";
}else {
$loggedIn = true;
$active = true;
$_SESSION['teacherid'] = $dbTeacherId;
$_SESSION['teacherusername'] = $dbTeacherUsername;
}
}
}
if ($loggedIn == true){
$_SESSION['teacherforename'] = $dbTeacherForename;
$_SESSION['teachersurname'] = $dbTeacherSurname;
header( 'Location: menu.php' ) ;
die();
}
if (!$loggedIn && $active && isset($_POST)) {
echo "<span style='color: red'>The Username or Password that you Entered is not Valid. Try Entering it Again</span>";
}
/* close statement */
$stmt->close();
/* close connection */
$mysqli->close();
}
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Teacher Login</title>
<link rel="stylesheet" type="text/css" href="TeacherLoginStyle.css">
</head>
<body>
<?php
include('noscript.php');
?>
<h1>TEACHER LOGIN</h1>
<form action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="post" id="teachLoginForm">
<p>Username</p><p><input type="text" name="teacherusername" /></p> <!-- Enter Teacher Username-->
<p>Password</p><p><input type="password" name="teacherpassword" /></p> <!-- Enter Teacher Password-->
<p><input id="loginSubmit" type="submit" value="Login" name="submit" /></p>
</form>
<a href="./forgotpass.php">Forgot Password</a>
</body>
<?php
}
?>
I have not changed the code where it checks to see if user is currently logged in or not, do I change it from if ((isset($username)) && (isset($userid))){ to anything relelvant?. I included the `include(sessionuser.php) code above
member.php script:
<?php
if (isset($_SESSION['teacherid'])) {
$userid = $_SESSION['teacherid'];
}
if (isset($_SESSION['teacherusername'])) {
$username = $_SESSION['teacherusername'];
}
?>
Do I still need the member.php script above?
sessionuser.php script:
$sessionUserID = false;
if (isset($_COOKIE['sessionUserID']) && preg_match('/^[a-z9-0]{32}$/i) {
$sessionUserID = $_COOKIE['sessionUserID'];
// Get the session details from the database
$sql = 'SELECT s.*, t.* FROM SessionUser s LEFT JOIN Teacher t ON s.TeacherId=t.TeacherId WHERE s.SessionUserId=:SessionUserId';
$aParams = array(':SessionUserId' => $sessionUserID)
$sessionRow = $stmnt->fetch();
if ($sessionRow) {
// User is logged in, and you have details in $sessionRow
// At this point, you can also validate other info such as the UserAgent, IP etc. All forgable, but can help add a littel security.
} else {
// Passed an invalid / expired session ID
$sessionUserID = false;
}
}
// If you don't have a session, create one
if (!$sessionUserID) {
// Create a session user ID - make it non sequential
// You should put this in a loop and check $sessionID is unique. Insert will fail is not unique
$sessionUserID = md5(time() . uniqid());
$sql = 'INSERT INTO SessionUser(SessionUserId, TeacherId)
VALUES(:SessionUserId, 0)';
$aParams = array(':SessionUserId' => $sessionUserID)
$smnt->execute();
// Default session details
$sessionRow = array('TeacherId'=>0);
// Now the cookie part
setcookie('sessionUserID', $sessionUserID, time() + howLongYouWant, '/');
}
// Not check for user logging in.
if (UserLogsIn) {
if ($sessionRow['teacher_id'] > 0) {
// Already logged in!?
} else {
$sql = 'UPDATE SessionUser SET Teacher_id=:TeacherId WHERE SessionUserId=:SessionUserId';
$aParams = array(':TeacherId'=>$TeacherId, ':SessionUserId' => $sessionUserID);
$smnt->execute();
// After a form post, always redirect to the same page or another page - stops the "do you want to resent this data" message on back button
// DO NOT echo anything before this point.
header('location: this page');
exit();
}
} elseif (UserLogsOut) {
if ($sessionRow['TeacherId'] == 0) {
// Not Logged In!?
} else {
$sql = 'UPDATE SessionUser SET TeacherId=0 WHERE SessionUserd=:SessionUserid';
$aParams = array(':session_id' => $sessionID);
$smnt->execute();
// After a form post, always redirect to the same page or another page - stops the "do you want to resent this data" message on back button
// DO NOT echo anything before this point.
header('location: this page');
exit();
}
}
IS it correct that the sessionuser.php script code contains all of the code above? I have changed the code to try and match the database table below:
SessionUser Table:
SessionUserId (CHAR32) PK
TeacherId (INT) //matches TeacherId field in teacher table
Is update 2 correct?
The simple (but wrong) answer is that you replace all
$_SESSION['blah'] = $valuewithsetcookie('blah', $value, time() + ages);But the problem you have is that you are storing user information in the session – and that information, if you store in a cookie, can easily be changed.
So you need a local (on server) way of storing the personal details, and a reference number to recall those details – essentially you need to replicate sessions but using your own database (or file store).
Commonly this is done in a database: you create a “session” database, give each user a unique sessionID (hard to guess, not a straight numeric) and then store that session ID in a cookie, and store the personal details in the database. Then you get a session cookie, recall their details from the database. When they log out, delete the entry in the databse etc. If the server reboots and you lose sessions, your session data is safe as it’s in the database – the user is always logged in until you don’t want it.
So there’s a simple answer, and the real, more complex answer.
EDIT:
As requested, an off-the-cuff process. I’ve missed off error checking and all that jazz for DB calls. This should get you started.