Advance Level Login system with Logic captcha. Long ago, we talked about a simple easy login system. And today, I decided to improve the system. The new version will use the methods SHA1 + MD5 (with salt) to encode passwords. We also do not use cookies to store information, and will use the sessions. And, in this version I will implement an interesting logic captcha (where we will need to choose the correct answer in order to prove that we are human, not machine).
[sociallocker]
[/sociallocker]
Our final result

OK, download the example files and lets start coding !
Step 1. HTML
As usual, we start with the HTML. This is main page code:
main_page.html
03 | <title>Advance Level Login system with Logic captcha</title> |
04 | <link rel="stylesheet" href="css/main.css" type="text/css" media="all" /> |
05 | <script src="js/jquery-1.4.4.min.js" type="text/javascript"></script> |
08 | <div class="example" id="main"> |
12 | <hr style="clear:both;" /> |
Here are all easy, isn’t it?. I just put one key {login_form} here, which we will use later.
02 | <a href="#" id="my_userarea">Log In</a> |
04 | <div style="display: none;" id="my_panel"> |
06 | <h3>My website title</h3> |
07 | <p>My website description. Our website was created for anybody. Here we can read recent news, tutorials, and find many useful information. Welcome !</p> |
08 | <p><a class="more" href="#about.php" rel="nofollow"><span>Read more</span></a></p> |
11 | <form class="login_form" action="index.php" method="post"> |
13 | <label>Nickname:</label><input type="text" name="username"> |
14 | <label>Password:</label><input type="password" name="password"> |
15 | <label>{captcha}</label><input type="text" name="captcha"> |
16 | <input type="submit" name="LogIn" value="Login"> |
17 | <a class="more" href="#forgot.php" rel="nofollow"><span>Forgot password?</span></a> |
21 | <h3>Still not our member? Join us!</h3> |
22 | <p>Which gives us a registration? This gives us opportunity to become full member of our website. You can communicate with another member etc..</p> |
23 | <p align="center"><a class="more" href="#registration.php" rel="nofollow"><span>Registration</span></a></p> |
25 | <div style="clear:both"></div> |
27 | <div class="close"><a id="my_close" class="my_close">Hide this panel</a></div> |
29 | <script language="javascript" type="text/javascript"> |
30 | $(document).ready(function() { |
31 | $('#my_userarea').click(function(){ |
32 | $('div#my_panel').slideToggle('slow'); |
35 | $('#my_close').click(function(){ |
36 | $('div#my_panel').slideUp('slow'); |
41 | <h3>You can use username "User1" of "User2" or "User3" and password "password" to login in system</h3> |
This file is a template of login form (with three columns). I added here new one key: {captcha}. I will replace this key to value (question) of our new Logic captcha. Last template file – logout:
2 | <a href="index.php?logout" id="my_userarea">Log Out</a> |
Step 2. CSS
Here are used CSS styles:
css/main.css
01 | body{background-color:#888;margin:0;padding:0} |
02 | .example{position:relative;width:980px;height:700px;background-image:url(../images/background.jpg);border:1px #000 solid;margin:20px auto;padding:20px;-moz-border-radius:3px;-webkit-border-radius:3px} |
03 | .bar{background-color:#444;height:24px;padding:10px} |
04 | a#my_userarea{font-size:12px;position:relative;display:block;overflow:hidden;color:#909090;-webkit-border-radius:11px;-moz-border-radius:11px;text-decoration:none;border-radius:11px;background:url(../images/button-user-area.gif) repeat-x 0 0;text-shadow:#000 1px 1px;float:right;padding:4px 10px 3px} |
05 | #my_panel{background-color:#272727;border:1px solid #444;color:#999;font-size:.85em;z-index:1001;padding:15px;position:absolute;width:948px} |
06 | #my_panel .column{float:left;width:30%;padding:15px} |
07 | #my_panel .column h3{color:#fff} |
08 | #my_panel .login_form input,#my_panel .login_form label{margin-bottom:5px;display:block} |
09 | #my_panel input[type=text],#my_panel input[type=password]{width:200px} |
10 | #my_panel input[type=submit]{background:url(../images/button.png) no-repeat scroll right 0 transparent;width:72px;height:30px;color:#fff;border-width:0} |
11 | .more{background:url(../images/more-left.png) no-repeat scroll 0 0 transparent;cursor:pointer;display:block;float:right;padding-left:11px;text-align:center;text-decoration:none} |
12 | .more span{background:url(../images/more-right.png) no-repeat scroll right 0 transparent;color:#fff;display:block;height:30px;line-height:29px;padding:0 19px 0 8px} |
13 | .more:hover{text-decoration:none;background-position:0 bottom} |
14 | .more:hover span,#my_panel input[type=submit]:hover{background-position:right bottom} |
15 | #my_panel .close{text-align:center} |
16 | #my_panel .close a{color:#07BBE2;cursor:pointer} |
Step 3. JS
For our example we only need jQuery library (for the effect of sliding)
js/jquery-1.4.4.min.js
Step 4. PHP
Our most important part of project – login functionality with captcha.
index.php
03 | if (version_compare(phpversion(), "5.3.0", ">=") == 1) |
04 | error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED); |
06 | error_reporting(E_ALL & ~E_NOTICE); |
08 | $oAdvancedLoginSystem = new AdvancedLoginSystem(); |
09 | $sLoginForm = $oAdvancedLoginSystem->getLoginBox(); |
10 | echo strtr(file_get_contents('main_page.html'), array('{login_form}' => $sLoginForm)); |
12 | class AdvancedLoginSystem { |
17 | function AdvancedLoginSystem() { |
19 | $this->aExistedMembers = array( |
20 | 'User1' => array('hash' => 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'salt' => 'testing'), |
21 | 'User2' => array('hash' => 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'salt' => 'testing'), |
22 | 'User3' => array('hash' => 'b88c654d6c68fc37f4dda1d29935235eea9a845b', 'salt' => 'testing') |
24 | $this->aQuestions = array( |
25 | 1 => array('q' => 'Winter hot or cold?', 'a' => 'cold'), |
26 | 2 => array('q' => '4 - 1 = ?', 'a' => '3'), |
27 | 3 => array('q' => 'Sun is blue or yellow?', 'a' => 'yellow'), |
28 | 4 => array('q' => 'Type "god" to process', 'a' => 'god'), |
29 | 5 => array('q' => '4 + 3 = ', 'a' => '7'), |
30 | 6 => array('q' => '10 > 5 ? (yes/no)', 'a' => 'yes') |
34 | function getLoginBox() { |
36 | require_once('logout_form.html'); |
37 | $sLogoutForm = ob_get_clean(); |
38 | if (isset($_GET['logout'])) { |
39 | if (isset($_SESSION['member_name']) && isset($_SESSION['member_pass'])) |
40 | $this->performLogout(); |
42 | if ($_POST['username'] && $_POST['password'] && $_POST['captcha']) { |
43 | if ($this->checkLogin($_POST['username'], $_POST['password'], false) && $this->aQuestions[$_SESSION['captcha']]['a'] == $_POST['captcha']) { |
44 | unset($_SESSION['captcha']); |
45 | $this->performLogin($_POST['username'], $_POST['password']); |
46 | return $sLogoutForm . '<h2>Hello ' . $_SESSION['member_name'] . '!</h2>'; |
49 | require_once('login_form.html'); |
50 | $sLoginForm = ob_get_clean(); |
51 | $sCaptcha = $this->getLogicCaptcha(); |
52 | $sLoginForm = str_replace('{captcha}', $sCaptcha, $sLoginForm); |
53 | return $sLoginForm . '<h2>Username or Password or Captcha is incorrect</h2>'; |
56 | if ($_SESSION['member_name'] && $_SESSION['member_pass']) { |
57 | if ($this->checkLogin($_SESSION['member_name'], $_SESSION['member_pass'])) { |
58 | return $sLogoutForm . '<h2>Hello ' . $_SESSION['member_name'] . '!</h2>'; |
63 | require_once('login_form.html'); |
64 | $sLoginForm = ob_get_clean(); |
65 | $sCaptcha = $this->getLogicCaptcha(); |
66 | $sLoginForm = str_replace('{captcha}', $sCaptcha, $sLoginForm); |
71 | function performLogin($sName, $sPass) { |
72 | $this->performLogout(); |
73 | $sSalt = $this->aExistedMembers[$sName]['salt']; |
74 | $sPass = sha1(md5($sPass) . $sSalt); |
75 | $_SESSION['member_name'] = $sName; |
76 | $_SESSION['member_pass'] = $sPass; |
79 | function performLogout() { |
80 | unset($_SESSION['member_name']); |
81 | unset($_SESSION['member_pass']); |
84 | function checkLogin($sName, $sPass, $isHash = true) { |
86 | $sSalt = $this->aExistedMembers[$sName]['salt']; |
87 | $sPass = sha1(md5($sPass) . $sSalt); |
89 | return ($sPass == $this->aExistedMembers[$sName]['hash']); |
92 | function getLogicCaptcha() { |
93 | $i = array_rand($this->aQuestions); |
94 | $_SESSION['captcha'] = $i; |
95 | return $this->aQuestions[$i]['q']; |
What we can see here: At the top, we simply creating instance of our class and call the method to render the login form. In the class constructor, we define an array of users with access to the system. Notice that now we have not only user name and it hashed password, but also Salt. All because we’re going to use SHA1 + MD5 encoding methods together to make more strong encryption. Also, I’m not forcing you to hardcode your users in class constructor like me, you can always store the user data anywhere else (in the database, or other cache files).
In addition to users, in the class constructor we see another array – this is our innovation – the logic captcha. Here I wrote an array of questions and answers for our captcha.
I hope that the rest logic is pretty clear to you. In the beginning we draw the login form. In this form we will draw our captcha (the question), and saving question ID in browser sessions. Suppose a user logs into the system. Here we checking entered data, hashing (SHA1+MD5+Salt) entered password (for verification with real hash code), and we checking entered answer from our captcha (as you remember – we already saved its ID in sessions). If everything correct – we allow to log in. Otherwise – we will draw notification (Username or Password or Captcha is incorrect). During login – we saving few params in sessions (member_name, member_pass) – possible you will use these params somewhere else. And last point – in case if we already have some info in sessions (member_name, member_pass) and this is correct params – we believe that the user is still in the system (maybe he just opened another page at your website via navigation).
Conclusion
I hope today’s article was very interesting for you. Who knows, maybe you decide to use it for your own site. Do not forget to thank for our work. Good luck in your work!