Beveiligen website met login en session

CMD FED Y2Q2W3 Workshop

Doel

Deze workshop staat in het teken van het maken van een login-pagina in PHP als onderdeel van een secured website.

Waarom een login-pagina?

Soms wil je dat alleen bepaalde personen toegang krijgen tot een bepaald deel van een website. Je kunt hier zelf iets voor maken waarbij gebruik wordt gemaakt van PHP en de superglobals $_SESSION en $_POST

Stel je wilt bepaalde pagina's op je website afschermen voor de buitenwereld. Alleen bepaalde gebruikers die ingelogd zijn krijgen deze beschikbaar.

Voorbeeld: http://mijn.postbank.nl

In de instructie van les 3 is het gebruik van superglobals aan bod geweest. Ook daar is al een klein beetje uitgelegd hoe een login constructie werkt. In deze workshop gaan we een werkende versie maken. Hierbij maken we nog GEEN gebruik van een database. Dit komt later dit kwartaal aan de orde. De usernames en passwords die we gaan gebruiken, plaatsen we 'hard-coded' in een PHP bestand, eventueel plaatsen we deze in een array. We hebben een login formulier nodig en een script dat de ingevoerde gegevens controleert. Vervolgens hebben we een pagina nodig die beveiligd gaat worden.

Schematisch


Uitleg schema

De pagina functions.php wordt in de andere php files ge-include. Hierin staan functions om de html op te bouwen. De pagina secure.php wordt gestart. Deze zou je ook index kunnen noemen, en is de template pagina voor iedere andere pagina die je wilt beveiligen met een login. Daarin is een controle opgenomen die controleert of een bepaalde session is gevuld.
Als de session is gevuld kan de pagina secure.php verder worden verwerkt. Als de session 'ingelogd' niet op TRUE staat dan wordt het loginscherm via login.php getoond:

Na het invullen van het scherm wordt er op LOGIN geklikt waarna er een script wordt gestart genaamd checklogin.php die de ingevulde gegevens controleert. Normaal gebeurt dat door een database te raadplegen, maar die hebben we nu even niet. We controleren de username en password in de code met een if statement, dus hard-coded.

Als de login goed is verlopen dan wordt de session gevuld, waarna de pagina secure.php weer wordt gestart. Nu is de session wel gevuld, dus nu gaat de pagina door met de verwerking van het beveiligde deel.
Als de login fout gaat zal er een melding worden getoond waarna je via een hyperlink door kan klikken naar het login-scherm van login.php:

Als de inloggegevens niet kloppen wordt een foutmelding weergegeven waarbij de mogelijkheid wordt geboden om door te klikken naar het loginscherm:



Als het inloggen goed gaat verschijnt dit scherm:

Als je op de link Uitloggen klikt wordt het volgende scherm getoond:


Praktijk

We gaan een constructie maken zoals hierboven beschreven. We gebruik dezelfde namen voor de betreffende pagina's.

stap 1
Maak de pagina functions.php
Hierin komen o.a. de functies die de html header en footer maken, XTHML 1.0 Strict compiant.
Gebruik voor de volgende code:

<?php
/////////////////////////////////////////////
// functions.php
/////////////////////////////////////////////
function create_header($title) {
// opbouw html header tm <body>
$header = '
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>'.$title.'</title>
</head>
 <body>';
   return ($header); // teruggeven aan aanroeper 
}
function create_footer() {
   // opbouw html afsluit tags </body> en </html> 
   $footer = "</body></html>";
   return ($footer); // teruggeven aan aanroeper 
}
?>

stap 2
Maak de pagina login.php
Dit is in feite het formulier waar je je logingegevens invult en verstuurt naar de controlepagina checklogin.php.
Gebruik de volgende code:

<?php 
/////////////////////////////////////////////
// login.php
/////////////////////////////////////////////
include ("functions.php"); // functions library
echo (create_header("login")); // show html header
?>
<h2>Inloggen</h2>
<form name="frmLogin" method="post" action="checklogin.php">
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>Username:&nbsp;</td>
<td><input name="username" type="text" size="20" maxlength="20" /></td>
</tr>
<tr>
<td>password:&nbsp;</td>
<td><input name="password" type="password" size="20" maxlength="20" /></td>
</tr>
<tr>
<td colspan=2>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><input type="submit" name="Submit" value=">>>>> LOGIN <<<<<" /></td>
</tr>
</table>
</form>
<?php
echo(create_footer()); // show html footer
?>
In het formulierveld met de naam ‘password' wordt gebruik gemaakt van type=”password” waardoor op het scherm niet zichtbaar wordt wat je intoetst.
Je ziet in bovenstaand script een action naar een php pagina, checklogin.php via de method "post".

stap 3
Maak de pagina checklogin.php
Hierin wordt de invoer uit het formulier gecontroleerd.
Gebruik de volgende code:

<?php
/////////////////////////////////////////////
// checklogin.php
/////////////////////////////////////////////
session_start(); // aanzetten gebruik sessions
// controleren of pagina correct is aangeroepen.
if (!empty($_POST)) {
   
   if ($_POST['username'] == 'admin' && $_POST['password'] == 'administrator')    {
   	$username = $_POST["username"];
   	$password = $_POST["password"];
   
   	// opslaan in session object
   	$_SESSION['username'] = $username; //kan ook in COOKIE
   	$_SESSION['password'] = $password; //kan ook in COOKIE
   	$_SESSION['ingelogd'] = TRUE; //OK, beetje dubbel want username en password heb je ook al
   
   	// redirect naar beveiligde pagina
   	header("Location: secure.php");
   } else {
   	// geen username gevonden, of ongeldig password.
   	include ("functions.php"); // functions library
   	$header = create_header("login error");
   	$melding = "<p>U hebt geen geldige combinatie van username en
   	password opgegeven.<br />
   	<a href=\"login.php\">Opnieuw inloggen</a><br /></p>";
   	$footer = create_footer();
   	$html = $header.$melding.$footer; //samenstellen html page
   	echo ($html); // tonen html page
   }
} else {
	// pagina was incorrect aangeroepen
   //direct doorsturen naar login.php
   header("Location: login.php");
}
?>

Je ziet in bovenstaand script dat indien de username en password kloppen, de pagina secure.php wordt aangeroepen dmv. header("Location: secure.php”)

stap 4
Maak de pagina secure.php
Dit is de pagina die beveiligd dient te worden. Deze pagina kun je tevens gebruiken als template voor andere te beveiligen pagina's.
Gebruik de volgende code:

<?php
/////////////////////////////////////////////
// secure.php
/////////////////////////////////////////////
session_start(); // aangeven gebruik sessions
include ("functions.php"); // functions library
// controle of session $_SESSION["username"] is gevuld
if (!isset($_SESSION["ingelogd"])) {
// NEE session is niet gevuld
header("Location: login.php");
} else {
// JA session is blijkbaar wel gevuld dus pagina kan worden opgebouwd en getoond
$header = create_header("welkom"); // build html header
$melding = "
<h2>Welkom op deze beveiligde pagina</h2>
U bent aangemeld als : ".$_SESSION["username"]."<br />
Uw wachtwoord is : ".$_SESSION["password"]." <br />
<hr />
<a href=\"logout.php\">Uitloggen</a>
";
$footer = create_footer(); // build html footer
$html = $header.$melding.$footer; // build html
echo ($html); // tonen html pagina
}
?>

stap 5
Maak de pagina logout.php
Hierin worden de session variabelen leeggemaakt mbv. session_unset() en wordt de session afgesloten. Gebruik de volgende code:

<?php
/////////////////////////////////////////////
// logout.php
/////////////////////////////////////////////
session_start(); // session gebruik starten
session_unset(); // alle session variabelen vrijgeven
session_destroy(); // session afsluiten
include ("functions.php"); // functions library
$header = create_header("logout pagina"); // opbouw html header
$melding = "
	<h2>Uitloggen</h2>
   <hr />
   U bent nu uitgelogd. <br />
   U kunt hier eventueel opnieuw <a href=\"login.php\">inloggen.</a>
";
$footer = create_footer(); // opbouw html footer
$html = $header.$melding.$footer; //samenstellen html page
echo ($html); // tonen html page
?>

That's all there is to it !!! Check the WORKING version HERE