JavaScript
  Home arrow JavaScript arrow Page 4 - Building a CHAP Login System: An Object-Or...
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
JAVASCRIPT

Building a CHAP Login System: An Object-Oriented Approach
By: Alejandro Gervasio
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 10
    2005-09-12

    Table of Contents:
  • Building a CHAP Login System: An Object-Oriented Approach
  • Using a procedural script: a quick overview of the previous login system
  • Taking the object-oriented approach: using a session handling class
  • Putting the pieces together: integrating the “ChallengeGenerator” class

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Building a CHAP Login System: An Object-Oriented Approach - Putting the pieces together: integrating the “ChallengeGenerator” class


    (Page 4 of 4 )

    Definitely, coupling the PHP class to the existing CHAP script is pretty straightforward, since I’ll only replace the pieces of procedural code with the class itself. Considering that the previous login system is quite familiar to you, below is the complete code that implements the system, this time utilizing the “ChallengeGenerator” class that you just saw:

    <?php
    /*
     * Begin of server-side processing
     */
    class ChallengeGenerator{
      // constructor
      function ChallengeGenerator($clearSession=true){
        if($clearSession){
          $this->clearVars();
        }
        session_start();
      }
      // public method clearVars()
      function clearVars(){
        // destroy existing session
        session_start();
        session_unset();
        session_destroy();
      }
      // public method setChallengeVar()
      function setChallengeVar($name='challenge'){
        if(!is_string($name)||!$name){
          trigger_error('Invalid variable name');
          exit();
        }
        // register session variable
        $_SESSION[$name]=$this->getRandomString();
      }
      // public method getSessionVar()
      function getChallengeVar($name){
        if(!$_SESSION[$name]){
          trigger_error('Invalid variable name');
          exit();
        }
        return $_SESSION[$name];
      }
      function deleteChallengeVar($name){
                if(!$_SESSION[$name]){
          trigger_error('Invalid variable name');
          exit();
        }
                unset($_SESSION[$name]);
      }
      // private method "getRandomString()"
      function getRandomString($length=40){
        if(!is_int($length)||$length<1){
          trigger_error('Invalid length for random string');
          exit();
        }
        $chars=
    "abcdefghijklmnopqrstuvwxyz
    ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $randstring='';
        $maxvalue=strlen($chars)-1;
        for($i=0;$i<$length;$i++){
          $randstring.=substr($chars,rand(0,$maxvalue),1);
        }
        return $randstring;
      }
    }
    // instantiate a ChallengeGenerator object
    $chlgen=&new ChallengeGenerator();
    // register challenge variable
    $chlgen->setChallengeVar();
    /*
     * End of server-side processing
     */
    ?>
    <!doctype html public "-//W3C//DTD HTML 4.01//EN">
    <html>
    <head>
    <title>CHAP LOGIN SYSTEM EXAMPLE</title>
    <script language="javascript" src="md5.js"></script>
    <script language="javascript">
    /*
     * validate form fields &
     * implement the Challenge Handshaking Authentication Protocol
     */
    function checkForm(){
      valid=true;
      // get 'userid' field
      var usrid=document.getElementById('userid');
      if(!usrid){return};
      if(!usrid.value){showError(usrid,'Enter your ID')};
      // get 'password' field
      var psw=document.getElementById('passwd');
      if(!psw){return};
      if(!psw.value){showError(psw,'Enter your password')};
      // get 'challenge' field
      var chlng=document.getElementById('challenge');
      if(!chlng){return};
      // make MD5 hash of password and concatenate challenge value
      // next calculate MD5 hash of combined values
      chlng.value=MD5(MD5(psw.value)+'<?php echo $chlgen->getChallengeVar
    'challenge')?>');
      // clear password field
      psw.value='';
      return valid;
    }
    /*
     * display error messages
     */
    function showError(obj,message){
      if(!obj.errorNode){
        obj.onchange=hideError;
        var p=document.createElement('p');
        p.appendChild(document.createTextNode(message));
        obj.parentNode.appendChild(p);
       obj.errorNode=p;
     }
      valid=false;
      return
    }
    /*
     * hide error messages
     */
    function hideError(){
      this.parentNode.removeChild(this.errorNode);
      this.errorNode=null;
      this.onchange=null;
    }
    /*
     * execute 'checkForm()' function when page is loaded
     */
    window.onload=function(){
      var W3CDOM=document.getElementById&&document.
      getElementsByTagName&&document.createElement;
      // check if browser is W3CDOM compatible
      if(W3CDOM){
        document.getElementsByTagName('form')
    [0].onsubmit=function(){
          return checkForm();
        }
      }
    }
    </script>
    </head>
    <body>
    <!-- login form -->
    <form method="post" action="processlogin.php">
    User ID <input type="text" name="userid" id="userid"/><br />
    Password <input type="password" name="passwd" id="passwd"/><br />
    <input type="hidden" name="challenge" id="challenge" />
    <input type="submit" name="login" value="Log In" />
    </form>
    </body>
    </html>

    With reference to the above snippet, you can appreciate that the programming logic is basically the same. I’ve only included the corresponding class for obtaining server-provided random seeds, but the rest of the script remains nearly identical. The only different piece of PHP code embedded into the markup involves calling to the “getChallengeVar()” method, illustrated in the following line:

    chlng.value=MD5(MD5(psw.value)+'<?php echo $chlgen-
    >getChallengeVar('challenge')?>');

    To complete the example, the PHP script that runs on the server for authenticating the client might be written in the following way:

    // include ‘challenge generator class’
    require_once('challengeclass.php');
    // include ‘MySQL abstraction class’
    require_once('mysqlclass.php');
    // instantiate a ChallengeGenerator object
    $chlgen=&new ChallengeGenerator(false);
    // get challenge variable
    $challenge=$chlgen->getChallengeVar('challenge');
    // get a "fresh" version of the page
    header('Cache-control:must-revalidate');
    // connect to MySQL
    $db=new MySQLarray('host'=>'host','user'=>'user','password'=>'password',
    'database'=>'database'));
    // run query to obtain user data
    $result=$db->query("SELECT userid,password FROM users WHERE
    userid='".$_POST['userid']."'");
    $row=$result->fetchRow();
    // check to see if user credentials are valid
    if(md5($row['password'].$challenge)==$_POST['challenge']&&$row
    ['userid']==$_POST['userid']){
      echo '<html><head><title>Login Successful</title><body><h1>Thank you for logging in!
    </h1></body></html>';
    }
    else{
      echo '<html><head><title>Access denied!</title><h1>Access
    denied!</h1></body></html>';
    }
    // delete session data and destroy session
    $chlgen->clearVars();

    Using an object-oriented approach, the authenticating script is much simpler to read and understand. First, I’ve included the “ChallengeGenerator” class along with a “MySQL” wrapping class, useful for performing database-related tasks. Then, a new “ChallengeGenerator” object has been instantiated, in order to get the “challenge” session variable previously registered on the login script. These steps are performed with the code listed below:

    // instantiate a ChallengeGenerator object
    $chlgen=&new ChallengeGenerator(false);
    // get challenge variable
    $challenge=$chlgen->getChallengeVar('challenge');

    Next, the script connects to MySQL, fetches the password and user ID that matches the ID entered by the user, and finally performs the client’s authentication by comparing the MD5 hashed values, in a manner similar to the process implemented in the procedural script. The following code is responsible for authenticating the client:

    if(md5($row['password'].$challenge)==$_POST['challenge']&&$row
    ['userid']==$_POST['userid']){
      echo '<html><head><title>Login
    Successful</title><body><h1>Thank you for logging in!
    </h1></body></html>';
    }
    else{
      echo '<html><head><title>Access denied!</title><h1>Access
    denied!</h1></body></html>';
    }

    At the end of the script, all of the session data is deleted and the session itself is destroyed:

    // delete session data and destroy session
    $chlgen->clearVars();

    Now, you have an object-oriented script that uses a CHAP system for logging into a web-based application. Of course, it’s just a matter of taste and particular needs what approach you’ll use within your programs. In either case, the system’s effectiveness is the same, since in all cases passwords are never transmitted as plain text. Even if you’re not well versed in cryptographic techniques, you can still use their benefits for improving the overall security of your website’s login forms.

    Conclusion

    Over this series, I’ve explained the advantages of implementing CHAP systems on login forms, as an efficient and easy-to-use technique to raise the security level for transmitting sensitive data, and particularly passwords, during the execution of web-based programs.

    Ranging from a procedural approach to an object-oriented method, you’ve been provided with enough code to play with, and start using the examples for your own convenience and purpose. Of course, I must thank Paul Johnston, who gently allowed me to use his excellent JavaScript MD5 library, throughout the examples developed in this series. Happy encrypting!


    DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

       · The final part of the series looks at an object-based approach to generate...
       · A very interesting article, (as far as it goes!)I have recently developed a...
       · Thank you for commenting on my article. Now, with reference to your problem, make...
       · Since my comment yesterday where I said I was having a problem with the results of...
       · Thank you for your reply. Also, I'm glad to know that you already solved the...
     

    JAVASCRIPT ARTICLES

    - Validating Digits and Dates with jQuery`s Va...
    - Validating Ranges, Emails, and URLs with jQu...
    - More Uses for the jQuery Tooltip Plug-in`s b...
    - Building Image-Based Tooltips with the jQuer...
    - Using the jQuery Tooltip Plug-in`s bodyHandl...
    - Using Rangelength, Min and Max with the Vali...
    - Using Minlength and Maxlength with the Valid...
    - Modifying Tooltip Coordinates with the jQuer...
    - Applying a Fade Out Effect with the jQuery T...
    - Tracking Mouse Movements with the jQuery Too...
    - Checking Online Forms with the Validator jQu...
    - Nested JavaScript Functions as Objects
    - The jQuery Tooltip Plug-in
    - Active Client Pages at the Server
    - ACP Tab Web Page







    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 6 Hosted by Hostway
    Stay green...Green IT