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> <link type="text/css" rel="stylesheet" href="css/style.css" /> </head> <body> <div id="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, this 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 --> <form action="login.php" method="post"> <div id="formHeader">Admin Login</div> <div id="formBody"> <div class="formField"> <input type="text" name="username" placeholder="Username" /> </div> <div class="formField"> <input type="password" name="password" placeholder="Password" /> </div> <div> <input type="submit" value="Login" class="customButton" /> </div> </div> <div id="userNotes"> <div>Username: subscriber</div> <div>Password: codeofaninja</div> <div><a href="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> <link type="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 --> <div id='successMessage'>You are logged in. :)</div> <div id='actions'> <a href='index.php?action=logout'>Logout?</a> | <a href='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:thin solid #000; width:300px; margin:7em auto 0 auto; } #formHeader{ border-bottom:thin solid gray; padding:10px; background:#f3f3f3; } #loginForm{ } .customButton { padding:5px; width:100%; -moz-box-shadow:inset 0px 1px 0px 0px #bbdaf7; -webkit-box-shadow:inset 0px 1px 0px 0px #bbdaf7; box-shadow:inset 0px 1px 0px 0px #bbdaf7; background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #79bbff), color-stop(1, #378de5) ); background:-moz-linear-gradient( center top, #79bbff 5%, #378de5 100% ); filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#79bbff', endColorstr='#378de5'); background-color:#79bbff; -moz-border-radius:6px; -webkit-border-radius:6px; border-radius:6px; border:1px solid #84bbf3; display:inline-block; color:#ffffff; font-family:arial; font-size:15px; font-weight:bold; text-decoration:none; text-shadow:1px 1px 0px #528ecc; cursor:pointer; } .customButton:hover { background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #378de5), color-stop(1, #79bbff) ); background:-moz-linear-gradient( center top, #378de5 5%, #79bbff 100% ); 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.
I created a post to Salt, Hash and Store Passwords Securely with Phpass.
If you're looking for another 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).
To those who still experience 'headers alread started' messages, you can add:
ob_start();
after your first php tag, yes, before session_start();
I created a post to Salt, Hash and Store Passwords Securely with Phpass.
If you're looking for another 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).
To those who still experience 'headers alread started' messages, you can add:
ob_start();
after your first php tag, yes, before session_start();
The Code of a Ninja Resources
For FREE programming tutorials, click the red button below and subscribe! :)
website