Sunday, July 6, 2014

Perl Login Script

This post is in continuation of the my last post, where we had prepared a simple html file(login form). A few things to recollect from that previous post are:

1. The html form is the front-end, i.e., the page visible to a user, which merely takes the data (username and password) from the user, and sends it, to a login script that would process it.
This tutorial is about writing THAT login script in Perl 5 programming language.

2. A good way to understand the "front-end" and "back-end" concepts is.. imagine a wall clock in your house. You can see the hands of the clock.. the digits 1 to 12, and the frame of the clock itself. That is the front-end.

The invisible machinery inside the wall-clock, that is running the minute and hour hands is the back-end.

Now,  we are going to write the script, that would do the authentication process. Here is what would basically happen (step-by-step logic).

1. Suppose the user has already submitted a combination "john" and "password123" through the HTML form we made earlier. The next obvious thing to do is to catch those incoming values, and store them in a empty container before processing.

2. Next the login script, would check in its own record, whether a user named "john" does exist or not, and if so, is his password actually is "password123" or in other words:  Do the credentials that the user submitted, and our own records, match?

3. There are two possibilities now. First, either they do not match, in which case, we should produce a error on the screen "username or password is incorrect". Or Second, where it is a match,.. then we have to redirect the user to the members area.

Now a important thing to note is that, creating and maintaining a members area .. is a lot of work, and a bit complex at this stage of learning, so its better, that we just print a simple text to the screen saying "Welcome John, we are glad to have you back." if the username-password combo is a match. This would keep things simple for now.

4. A important question .. is where exactly does the server keep its own records of all the users and their passwords? The answer is, in general.. it is stored in a database. But that would require us to write more complex code here, that makes a connection to a database, retrieves the records, and close the connection, besides initially having to setup the database itself. Now I don't want to make things that complex for you, so lets keep it simple for now.

We will put the server side of records (of username/passwords) in a simple text file, and retrieve values from there. Though in real world it is a highly unsafe method .. security wise.. but since we are only doing this for learning purpose, its probably okay.. so relax :)

Here is the code for doing all of the above:



Now, here is the explanation for the above code:

Line 1:   #!<some path> ----> this is required for your script to work, it tells where the perl files are located.  #!/usr/bin/perl is saying that perl files are located in a local folder, which is located at /user/bin/perl

While -T is for taint mode (a security feature) and w is for warnings.

But using "# some text here" is a comment. See Line 6, 13, 17, 21 and 24.

Line 2: use strict is a security feature, and is strongly recommended!

Line 3:  CGI, when implemented on a web server, provides an interface between the web server and programs that generate the web content. CGI is a module, that is generally installed with the core Perl files i.e., usually you don't need to install it .. because it is already installed if you installed Perl on your computer.

A module is a program in perl, that automatically does some work for you if you give it certain input.

Line 4: Notice this line carefully, as I have written in the comment.. it basically shows any errors that arise upon the execution of your script in your browser. I recommend strongly to use this line while writing a new script or making changes to a existing one.. so if you make a mistake, it will tell you where and what is that mistake. But in practice, after the script is finalized, you should remove this line, for security purposes.

Line 7:  This shows..  how we create and manipulate a string. A string is basically a container, in which you can hold some data.. like numbers and words.

in perl it is required, that the string must be first declared in this manner: 

my $stringname = ""; 
#notice this is a empty container/string like a empty bucket

the word "my" is required just once only, not more or less.. before the string is used anywhere, it must be declared with the word "my".  Further on, in:

my $cgi = CGI->new;

 We are simultaneously creating a string named cgi (can be changed to anything) and declaring that it is a new and empty string made using the CGI module.

We have creating this string to catch all the incoming data in one place, and then pick and sort the relevant data from it.

For example, in fishing, we catch all sort of fishes in a big net first. We bring the net with fishes in it .. to the shore, and then sort different type of fishes, and put them in separate containers. Like Tuna Fish in a different container, and Salmon in a different container. And if you have accidentally caught a Shark, which you were not supposed to.. you can throw it back into the ocean

Line 8: We have declared the string called username .. as a empty (undef is short for undefined) perl string (not CGI, hence it is local and safe). It is very important to create the container, in which you would hold the username sent by the html form as empty in the beginning. The reason for doing this, is that every time the script is run, the container would become empty again, and the username submitted by previous user would not remain in that string.

Line 9: Now.. as I had said earlier.. we have caught all the incoming data from our html form into a big net.. into a string called cgi. In line 9, we are picking the actual username (for example john) from our bigger net .. which is the $cgi.

Line 10: Similarly to line 8, we have again created a empty perl string, to hold the actual password into it.

Line 11: Similarly to line 9, we have picked the password (our example: password123) from the cgi string, and put it in the string named password.

As you may figure, you can name the string anyway you like.. but notice the part:

param->('password');

We are basically saying that the incoming password (which is password123) would be given a name password by the html form, to recognize the fact.. that this is a password. If you change the word 'password' in the perl login script, which we are writing, you must change the name="password" in our html form (which we covered in previous tutorial) to the same value.

Line 14 and 15:
This is a basic of the basic, security measure. It is basically saying.. that the actual value of the username and password submitted by the user.. should not contain any other characters than:

a-z (lower case English alphabets)
A-Z (upper case English alphabets)
0-9 (numbers)

i.e., in the html form.. if the user submits a username or password containing any special character.. like a dollar sign (' $ ') or a slash (' / ') ... our script would stop working (die) and throw a error saying "Illegal Characters ".

Line 18: As I told you earlier above, that the best way in real world is to store the server-side copy of  username and password combo in a database. But since it would be complex to setup a database and write code for it... here for learning purpose only, we would use a simple txt file.

Basically in the txt file, the username and passwords of all users are just written one after another as simple clear text. For example this is the username/password combo of 3 users:

john      password123
elena     cutepass
chris      blablabla

Inside the txt file, it looks like this:
johnpassword123elenacutepasschrisblablabla

In line 18, we are simply just saying.. where that text file is located. Notice that the dot and slash before the file name says, that the file is located in the same folder as login script itself. This is a safer way to do things. Though using
my $file = 'userpass.txt'; 

Would work as well, but it is a security wise, inferior code.

Line 19: In line 18, we have only declared, where our file is located and its name. In line 19, we are  we are creating a string, and simultaneously saying that load all the text from our file (from line 18)  into this string.

A important thing to learn here is.. that when the value of a string or an array (which we would cover later) is declared as " do { some instructions here}" ... then the value of that string is the calculation or some piece of code.

The code inside the do statement here, is how to read the content of a file else throw a error.

At this point in the script, the string called $serverrecords contains the username and password of all the users. You can see now that it is a inefficient thing. This is also why we use database in real world practice to store username and passwords. so that we only retrieve the username and password that is needed here.

Line 22: Before we compare .. what the client submitted.. and what we have in our records.. we must prepare the client submitted info in a appropriate manner. Based on Line 18 where I showed you how the inside of txt file would look like.. we will ready the user submitted data in a similar manner.

Meaning, that if the username and password submitted by the user was "john" and "password123", in order to compare it to our records, we will join these two different values into one as "johnpasssword123".

Line 25:
This is a method called indexing in perl. Its purpose is to compare two strings.. to check if the value inside the string written first, contains the value inside the string written after it.

at this point in code, the string is checking, if the string 1, which is $serverrecord .. and its value being johnpassword123elenacutepasschrisblablabla contains the value inside the string 2 ( $clientrecord) whose value is johnpassword123.

So if the text file does not not contains the value johnpassword123, the value of the string $match would become -1, if it does contain johnpassword123 in our case, it would change the value of string $match to.. "1" because the it begins at the very first letter in the text file.

Line 27: This line is very very important, and you would need to use it in all pages generally. It says, that after this whatever is accompanied with a print command, is shown on the monitor.

Line 29 and 30: This is a simple

if (some condition) { then do this} else {do this} 

As you may figure from the code, if the value of match changes to -1, the the username-password combo was wrong, and we simply print a error statement. If it was not wrong, then we print a congrats .. you logged in.. message "Welcome John, we are glad to have you back" in the browser on top-left.. similarly to our hello world text (which we covered in our another tutorial earlier)

Tada! Now together with the html form, this perl script, and a simple txt file(containing username passwords), you now have a working login system on your website :)

Thanks for reading !!