Hi there! Today we are going to code one of the very basic requirement of a PHP web app - a PHP login script. This post also covers the log-out script. We are going to manage these tasks with the help of PHP sessions. A PHP session consists of a way to preserve certain data that can be used across different pages or section of your website.
- Show user a login form (login.php) and validate the inputs when the "Login" button was clicked. It will either say "Access Denied" if the login failed, or else, be redirected to the index page (main page of your web app, index.php).
- When the user is not yet logged in and tried to go to the index page directly via pasting the URL, he will be redirected to the login page with a message "You cannot go to the index page because you are not yet logged in."
- When the user is already logged in and tried to go to the login page, he will be redirected to the index page and tell him "You cannot go to login page because you are already logged in."
login.php - will show the login form where the user can enter his username and password. Please note that we didn't use a database to get and match the entered username and password since we are just taking a look on how a PHP login script works. If you want to integrate this with a database, this is a nice start: PDO read records.
<?php
// STEP 1. Start the PHP session.
// should be the first to start, to prevent 'headers already sent' errors
session_start();
// STEP 2. Check if a user is logged in by checking the session value
if($_SESSION['logged_in']==true){
// if it is, redirect to index page and tell the user he's already logged in
header('Location: index.php?action=already_logged_in');
}
?>
<html>
<head>
<title>www.codeofaninja.com - php login script</title>
<linktype="text/css"rel="stylesheet"href="css/style.css" />
</head>
<body>
<divid="loginForm">
<?php
// STEP 3. Check for an action and show the approprite message.
if($_GET['action']=='not_yet_logged_in'){
echo"<div id='infoMesssage'>You cannot go to the index page because you are not yet logged in.</div>";
}
// STEP 4. Check if the user clicked the 'Login' button already by checking the PHP $_POST variable
if($_POST){
// these username and password are just examples, it should be from you database
// passwords must be encrypted (salt and hash) to be secured, my old post should give you an idea or see the update below
$username='subscriber';
$password='codeofaninja';
// check if the inputted username and password match
if($_POST['username']==$username&&$_POST['password']==$password){
// if it is, set the session value to true
$_SESSION['logged_in'] =true;
// and redirect to your site's admin or index page
header('Location: index.php');
}else{
// if it does not match, tell the user his access is denied.
echo"<div id='failedMessage'>Access denied. :(</div>";
}
}
?>
<!-- where the user will enter his username and password -->
<formaction="login.php"method="post">
<divid="formHeader">Admin Login</div>
<divid="formBody">
<divclass="formField">
<inputtype="text"name="username"placeholder="Username" />
</div>
<divclass="formField">
<inputtype="password"name="password"placeholder="Password" />
</div>
<div>
<inputtype="submit"value="Login"class="customButton" />
</div>
</div>
<divid="userNotes">
<div>Username: subscriber</div>
<div>Password: codeofaninja</div>
<div><ahref="index.php">Go to index page</a></div>
</div>
</form>
</div>
</body>
</html>
index.php - contains your main page, can be your admin page or the user dashboard. This will be shown when the user has successfully login to the system.
<?php
// STEP 1. Start the PHP session.
// should be the first to start, to prevent 'headers already sent' errors
session_start();
// STEP 2. Check if a user is NOT YET logged in by checking the session value
if(empty($_SESSION['logged_in'])){
// if the session value is empty, he is not yet logged in
// redirect him to login page
header('Location: login.php?action=not_yet_logged_in');
}
?>
<html>
<head>
<title>Sucessful Login</title>
<linktype="text/css"rel="stylesheet"href="css/style.css" />
</head>
<body>
<?php
// STEP 3. get and check the action
// action determines whether to logout or show the message that the user is already logged in
$action=$_GET['action'];
// executed when user clicked on "Logout?" link
if($action=='logout'){
// destroy session, it will remove ALL session settings
session_destroy();
//redirect to login page
header('Location: login.php');
}
else if($action=='already_logged_in'){
echo"<div id='infoMesssage'>You cannot go to login page because you are already logged in.</div>";
}
?>
<!-- some contents on our index page -->
<divid='successMessage'>You are logged in. :)</div>
<divid='actions'>
<ahref='index.php?action=logout'>Logout?</a> | <ahref='login.php'>Go to login page</a>
</div>
</body>
</html>
style.css - for our user interface. As for the message boxes, you can improve it by adding an icon or border such as the one I used here: Four message boxes with CSS.
body{
font:20px"Lucida Grande", Tahoma, Verdana, sans-serif;
color:#404040;
}
input[type=text],
input[type=password]{
padding:10px;
width:100%;
}
#userNotes{
font-size:0.7em;
text-align:left;
padding:10px;
}
#actions{
padding:10px;
}
#infoMesssage{
padding:10px;
background-color:#BDE5F8;
color:black;
font-size:0.8em;
}
#successMessage{
padding:10px;
background-color:green;
color:white;
}
#failedMessage{
padding:10px;
background-color:red;
color:white;
font-size:15px;
}
#formBody{
padding:5px;
}
#loginForm{
text-align:center;
border:thinsolid#000;
width:300px;
margin:7emauto0auto;
}
#formHeader{
border-bottom:thinsolidgray;
padding:10px;
background:#f3f3f3;
}
#loginForm{
}
.customButton {
padding:5px;
width:100%;
-moz-box-shadow:inset0px1px0px0px#bbdaf7;
-webkit-box-shadow:inset0px1px0px0px#bbdaf7;
box-shadow:inset0px1px0px0px#bbdaf7;
background:-webkit-gradient( linear, lefttop, leftbottom, color-stop(0.05, #79bbff), color-stop(1, #378de5) );
background:-moz-linear-gradient( centertop, #79bbff5%, #378de5100% );
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#79bbff', endColorstr='#378de5');
background-color:#79bbff;
-moz-border-radius:6px;
-webkit-border-radius:6px;
border-radius:6px;
border:1pxsolid#84bbf3;
display:inline-block;
color:#ffffff;
font-family:arial;
font-size:15px;
font-weight:bold;
text-decoration:none;
text-shadow:1px1px0px#528ecc;
cursor:pointer;
}
.customButton:hover {
background:-webkit-gradient( linear, lefttop, leftbottom, color-stop(0.05, #378de5), color-stop(1, #79bbff) );
background:-moz-linear-gradient( centertop, #378de55%, #79bbff100% );
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#378de5', endColorstr='#79bbff');
background-color:#378de5;
}
.customButton:active {
position:relative;
top:1px;
}
/* This imageless css button was generated by CSSButtonGenerator.com */
Update: As @ccornutt suggests in a comment below, I should emphasize something about how to hash and salt (not really encrypt) login passwords. If you're looking for a good tool for password hashing, check out this project: https://github.com/ircmaxell/password_compat (or, if you're on PHP 5.5+ you can just use the password_hash() function natively).