Very simple login using Perl, jQuery, Ajax, JSON and MySQL

Everyday hundreds of new domains are being registered and as many web sites are being launched. The majority of these web sites host web applications with a login feature.

This article describes a very simple login technique implemented by using several contemporary technologies. It brings a scripting language (Perl), a free database (MySQL) together with a lightweight text-based open standard (JSON), a cross-browser JavaScript library (jQuery) and an asynchronous interactive web application technique (Ajax).

Seda Özses, IT Specialist, IBM

Photo of Seda OzsesSeda Özses は ibm.com 全体を統括するウェブマスター・チームのメンバーです。彼女は主に ibm.com 全体としての Web ポータルを担当しており、XSL に関する作業と、彼女のチームに必要なさまざまな要件を管理しています。



25 January 2011

Also available in Russian Japanese

Introduction

Since the beginning of the WWW, the developers try to equip their Web sites with new features and widgets to attract the users' attention and make the life much easier for them by applying the latest technologies. Nowadays, an average Web user, among other activities, shops, searches for information, registers to forums and communities, plays online games and communicates with the other users on the Internet. For most of these activities the user typically needs to register and then log in to the Web site. These basic features require special care; they need to be simple, fast and secure for the user. From the developer's perspective, thanks to the new techniques, the implementation of these features gets easier every day.

In this article, you will learn how to bring a handful of these technologies together and implement a very simple login feature for your Web site.

The implementation has been broken down into 4 sections:

  1. The SQL section defines how to create a table to store the user information in the database.
  2. The HTML section implements the CSS and JavaScript references as well as the login form.
  3. The JavaScript section takes care of the Ajax part by using jQuery and JSON.
  4. Finally the Perl section supplies the interaction between the user input and the database.

In the instructions section you will find step by step instructions on how to put everything together. The article assumes, that you are already familiar with the named technologies and have web development experience. If you are experienced enough in these technologies, you can skip directly to the instructions section.

What is not included in the article?

It is also important to note that, security, e.g. checking the user's input for possible data and system threats, is not a topic of this article. So are not any encryption methods for saving the user's password. However, it is strongly recommended to learn about the possible vulnerabilities of your system and build these features into your code.

SQL

As this is a very simple login technique, the users table consists of only 3 fields; a unique id, a unique username and a password.

Listing 1. SQL code
CREATE TABLE `mydb`.`users` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `username` VARCHAR(45) NOT NULL ,
  `password` VARCHAR(45) NOT NULL ,
  PRIMARY KEY (`id`) ,
  UNIQUE INDEX `id_UNIQUE` (`id` ASC) ,
  UNIQUE INDEX `username_UNIQUE` (`username` ASC)
);
COMMIT;

The actual data insertion and validation of uniqueness are to be taken care by the registration feature, thus they are not part of this article. We assume that the users table is already filled with the appropriate user information, which will be required for the login implementation.

For testing purposes though, you might want to use the following code which inserts 2 simple entries into the users table:

INSERT INTO `mydb`.`users` (`id`, `username`, `password`) 
  VALUES(1, 'username1', 'password1');
INSERT INTO `mydb`.`users` (`id`, `username`, `password`) 
  VALUES(2, 'username2', 'password2');
COMMIT;

If you are not using MySQL, then the SQL syntax of your database might be slightly different than the one of MySQL.


HTML

The HTML file contains the login form as well as the CSS and JavaScript file references.

CSS references

For the simplicity, the article concentrates more on the implementation of the named technologies rather than the design of the login form, thus it uses an already available source with a modified MIT License called Blueprint CSS framework which also ensures cross-browser compatibility. There are of course many more free CSS implementations for various designs on the Internet.
Refer to Resources for more information about the Blueprint framework.

<link rel="stylesheet" type="text/css" media="screen, projection" 
  href="http://www.blueprintcss.org/blueprint/screen.css" />
<link rel="stylesheet"  type="text/css" media="screen, projection"
  href="http://www.blueprintcss.org/blueprint/plugins/buttons/screen.css" />
<link rel="stylesheet" type="text/css" media="print" 
  href="http://www.blueprintcss.org/blueprint/print.css" />
<!--[if IE]><link rel="stylesheet" type="text/css" media="screen, projection" 
  href="http://www.blueprintcss.org/blueprint/ie.css"><![endif]-->

JavaScript references

In addition to the jQuery library, there is also a reference to the JavaScript file (login.js) which will be explained later in this article.

<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="login.js"></script>

At the time of the publication the version of jQuery was 1.4.4, refer to Resources for picking the latest version.

Login form

The login form consists of a username text field, a password field and a submit button.

<form id="loginForm" name="loginForm" method="post" action="">
  <fieldset>
    <legend>Enter information</legend>
    <p>
      <label for="username">Username</label>
      <br />
      <input type="text" id="username" name="username" class="text" size="20" />
    </p>
    <p>
      <label for="password">Password</label>
      <br />
      <input type="password" id="password" name="password" class="text" size="20" />
    </p>
    <p>
      <button type="submit" class="button positive">
       <img alt="ok" src=
       "http://www.blueprintcss.org/blueprint/plugins/buttons/icons/tick.png" /> 
       Login
      </button>
    </p>
  </fieldset>
</form>

A Captcha could be used for testing the origin of the input, i.e. if it is coming from a human or is being generated by a computer.
Refer to Resources for more information about Captcha.

Figure 1. Screen capture of the login form
Screen capture of the login form

Displaying the result

The result of the login action will be displayed in a div tag which is hidden at the load time and gets filled in later by JavaScript.

<div id="loginResult" style="display:none;">
</div>
Figure 2. Screen capture of the error message returned by the JavaScript
Screen capture of the error message returned by the JavaScript
Figure 3. Screen capture of the error message returned by the Perl script
Screen capture of the error message returned by the Perl script
Figure 4. Screen capture of the success message returned by the Perl script
Screen capture of the success message returned by the Perl script

The complete HTML code

Listing 2. login.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Very simple login using Perl, jQuery, Ajax, JSON and MySQL</title>
    <link rel="stylesheet" type="text/css" media="screen, projection" 
      href="http://www.blueprintcss.org/blueprint/screen.css" />
    <link rel="stylesheet"  type="text/css" media="screen, projection"
      href="http://www.blueprintcss.org/blueprint/plugins/buttons/screen.css" />
    <link rel="stylesheet" type="text/css" media="print" 
      href="http://www.blueprintcss.org/blueprint/print.css" />
    <!--[if IE]><link rel="stylesheet" type="text/css" media="screen, projection" 
      href="http://www.blueprintcss.org/blueprint/ie.css"><![endif]-->
    <script type="text/javascript" 
      src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
    <script type="text/javascript" src="login.js"></script>
    <style type="text/css">
      #loginContent { width: 350px; margin: 100px auto; }
      button[type] { margin: 0.5em 0; }
    </style>
  </head>
  <body>
    <div id="loginContent" class="container">
      <div id="loginResult" style="display:none;">
      </div>
      <form id="loginForm" name="loginForm" method="post" action="">
        <fieldset>
          <legend>Enter information</legend>
          <p>
            <label for="username">Username</label>
            <br />
            <input type="text" id="username" name="username" class="text" size="20" />
          </p>
          <p>
            <label for="password">Password</label>
            <br />
            <input type="password" id="password" name="password" class="text" size="20" />
          </p>
          <p>
            <button type="submit" class="button positive">
             <img alt="ok" src=
             "http://www.blueprintcss.org/blueprint/plugins/buttons/icons/tick.png" /> 
             Login
            </button>
          </p>
        </fieldset>
      </form>
    </div>
  </body>
</html>

Although CSS is not of primary concern, there are two additional inline definitions in the HTML code for making the form and the button look a bit nicer.

Code validation

The HTML code and the additional CSS definitions have been validated by the W3C Validation Services.
Refer to Resources for more information about the W3C Validation Services.


JavaScript

When the user submits the login form, the input is read by the jQuery library. After passing a very simple test to check if any empty field has been submitted, an Ajax call is made to the Perl script (login.pl). The key in the Ajax call is setting the dataType parameter to json.

According to the result of the script call, either error or success functions are invoked. In this code sample, both functions write the result to the div tag with the loginResult id.

In case of a failure, the sample code displays the XMLHttpRequest.responseText, textStatus and errorThrown which are provided by jQuery.

If the script call was successful, then its response is tested. If the response variable data does not contain an error message, then along with a success message, the id of the user is displayed which is retireved from the users table by the Perl script. In case of success the code sample hides the form itself and displays only the div tag.

The complete JavaScript code

Listing 3. login.js
$(document).ready(function(){
  $("form#loginForm").submit(function() { // loginForm is submitted
    var username = $('#username').attr('value'); // get username
    var password = $('#password').attr('value'); // get password

    if (username && password) { // values are not empty
      $.ajax({
        type: "GET",
        url: "/cgi-bin/login.pl", // URL of the Perl script
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        // send username and password as parameters to the Perl script
        data: "username=" + username + "&password=" + password,
        // script call was *not* successful
        error: function(XMLHttpRequest, textStatus, errorThrown) { 
          $('div#loginResult').text("responseText: " + XMLHttpRequest.responseText 
            + ", textStatus: " + textStatus 
            + ", errorThrown: " + errorThrown);
          $('div#loginResult').addClass("error");
        }, // error 
        // script call was successful 
        // data contains the JSON values returned by the Perl script 
        success: function(data){
          if (data.error) { // script returned error
            $('div#loginResult').text("data.error: " + data.error);
            $('div#loginResult').addClass("error");
          } // if
          else { // login was successful
            $('form#loginForm').hide();
            $('div#loginResult').text("data.success: " + data.success 
              + ", data.userid: " + data.userid);
            $('div#loginResult').addClass("success");
          } //else
        } // success
      }); // ajax
    } // if
    else {
      $('div#loginResult').text("enter username and password");
      $('div#loginResult').addClass("error");
    } // else
    $('div#loginResult').fadeIn();
    return false;
  });
});

Perl

For a very simple implementation only 3 modules are required in Perl; CGI, DBI and the DBD::mysql. With the help of the CGI module, the Perl script gets the username and password values sent by Ajax. Then the script connects to the database and makes a query to select the user id for the given values. Based on the query result, a JSON response is built with either an error message or a success message and the user id. The Perl script sets the content type to application/json and responds to Ajax with the JSON string which is then caught in the data variable by jQuery.

The complete Perl code

Listing 4. login.pl
#!/usr/bin/perl -T
use CGI;
use DBI;
use strict;
use warnings;

# read the CGI params
my $cgi = CGI->new;
my $username = $cgi->param("username");
my $password = $cgi->param("password");

# connect to the database
my $dbh = DBI->connect("DBI:mysql:database=mydb;host=localhost;port=2009",  
  "mydbusername", "mydbpassword") 
  or die $DBI::errstr;

# check the username and password in the database
my $statement = qq{SELECT id FROM users WHERE username=? and password=?};
my $sth = $dbh->prepare($statement)
  or die $dbh->errstr;
$sth->execute($username, $password)
  or die $sth->errstr;
my ($userID) = $sth->fetchrow_array;

# create a JSON string according to the database result
my $json = ($userID) ? 
  qq{{"success" : "login is successful", "userid" : "$userID"}} : 
  qq{{"error" : "username or password is wrong"}};

# return JSON string
print $cgi->header(-type => "application/json", -charset => "utf-8");
print $json;

Code validation

In order to build a valid JSON response, you might want to use a JSON validator.
Refer to Resources for more information about JSON validation.

Displaying the generated JSON string

You can check your JSON string in your browser:

  1. Change $cgi->header(-type => "application/json", -charset => "utf-8"); to print $cgi->header;
  2. Type http://your-domain-name_or_localhost/cgi-bin/login.pl?username=username1&password=password1 to your browser.
Figure 5. Screen capture of the JSON string
Screen capture of the JSON string

Instructions

  1. Create the users table with the SQL code (change mydb to the appropriate value), and fill it with some test data.
  2. Copy and paste login.html and login.js to the htdocs folder of your web server. The folder name might vary according to the settings of your web server.
  3. Copy and paste login.pl to the cgi-bin folder of your web server. The folder name might vary according to the settings of your web server.
  4. Change the first line of the Perl script according to your version (mostly #!/usr/bin/perl for Unix and #!\Perl\bin\perl.exe for Windows) and also mydb, localhost, 2009, mydbusername and mydbpassword to the appropriate values.
  5. Type http://your-domain-name_or_localhost/login.html to your browser.
  6. Enter correct and also wrong values as username and password to check the various outcome.

Important

Make sure that you have the HTML, JavaScript and Perl files hosted on the same domain. Otherwise when Ajax tries to call your Perl script which is not hosted on the same domain as the calling script you would be violating the same origin policy thus having an error (data variable is null). Furthermore the HTML file must be served by the web server because of the same reason.
See Resources for more information about the same origin policy.


Conclusion

The intention of the article is to give you a really simple code with contemporary techniques, that you can use as a good starting point for implementing a login service. You can build many fancy features on top of it, including security. You might even want to use other databases and programming languages once you get the idea.

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into SOA and web services on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=SOA and web services, Web development
ArticleID=618772
ArticleTitle=Very simple login using Perl, jQuery, Ajax, JSON and MySQL
publish-date=01252011