Simple Login, Logout & Sessions in PHP

Tuesday, June 8, 2010 1:34

I am going to provide an overview of how I got the login system on my website to work. I will start by mentioning this should not be used to protect sensitive information (ie: health records) because it uses a table you add to your database. The table I used is:

User table stored in database.
Column Data Type Null Primary Key Other
user_id int No PK Auto Increment
username varchar(11) No   Unique
password varchar(32) No  
permission enum(‘ADMIN’,'GUEST’) No    

When adding a new user you have to make sure to apply the function MD5 to the value being added to the password field so it is not stored in plain text. The reason for the 32 character length is that the MD5 value generated is 32 characters long. I made the username column unique so that no user will have the same name. I use the permissions column by storing the username of who is logged into the current session so that I can determine if they are an administrator (ADMIN) so that I provide the user the option to insert, delete, and update records in the database.

Now that you have an idea of what I am trying to do, we have to use this table and the functionality PHP provides to create our login system. To make this work you will need three or four files (index.php, login.php, checkLogin.php, logout.php) which I will show you and explain some of the logic behind them.

Request Credentials

The first stage is to create your index.php file, which will be the first page your users see, before entering your ‘restricted’ area, to provide their credentials to gain access.

index.php
————————————————————————-
<?php
$error = “Please login to access the database.”;
if(isset($_REQUEST["error"])){
$error = $_REQUEST["error"];
}
?>
<html>
<head>
<title>Login</title>
</head>
<body>
<center>
<?php
echo $error;
?>
<form method=”POST” action=”login.php”>
Username: <input type=”text” name=”username” size=”20″>
Password: <input type=”password” name=”password” size=”20″>
<input type=”submit” value=”Submit” name=”login”>
</form>
</center>
</body>
</html>
————————————————————————-

The first section before the open html tag is used to see if we (the programmers) have passed a variable error with a value to be used within this page. The rest is to provide a basic user interface to prompt the user for their username and password to be submitted. The action of our post is login.php, which is where the values of our form will be sent to for processing, which leads into the second step.

Verify Credentials

Now we have to check to make sure the username and password provided is valid, which is done in login.php.

login.php
————————————————————————-
<?php
//check that the user is calling the page from the login form and not accessing it directly
//and redirect back to the login form if necessary

if (!isset($_POST['username']) || !isset($_POST['password'])) {
header( “Location: index.php?error=You must login first” );
}
//check that the form fields are not empty, and redirect back to the login page if they are
elseif (empty($_POST['username']) || empty($_POST['password'])) {
header( “Location: index.php?error=Username or password was blank” );
}
else{
//convert the field values to simple variables
//add slashes to the username and md5() the password
$user = addslashes($_POST['username']);
$pass = md5($_POST['password']);
//set the database connection variables
$dbHost = “ip address”;
$dbUser = “username”;
$dbPass = “password”;
$dbDatabase = “database name”;
//connect to the database

$db = mysql_connect(“$dbHost”, “$dbUser”, “$dbPass”) or die (“Error connecting to database.”);

mysql_select_db(“$dbDatabase”, $db) or die (“Couldn’t select the database.”);

$result=mysql_query(“select * from user where username=’$user’ AND password=’$pass’”, $db);

//check that at least one row was returned

$rowCheck = mysql_num_rows($result);

if($rowCheck > 0){
while($row = mysql_fetch_array($result)){

//start the session and register a variable

session_start();
session_register(‘user’);
$_SESSION['l_user'] = $user;

//successful login code will go here…

//we will redirect the user to another page where we will make sure they’re logged in
header( “Location: main.php” );

}
}
else {
//if nothing is returned by the query, unsuccessful login code goes here…
header( “Location: index.php?error=Check username and password” );
}
}
?>
————————————————————————-

Firstly, we gather the values for the username and password that we passed from our login form.  Then check to make sure that neither is empty, and if they are then we know it is not valid and we redirect the user back to the login form with header( “Location: index.php?error=Username or password was blank” );, otherwise we continue and md5 the password for comparison with the value stored in the database.

We then connect to the database and select the username and md5 version of the password from the user table, if the number of rows returned is 1 (shouldn’t be more as we have the username being unique) then they are a valid user and we start a session (session_start()) and register the session (register_session($user)) providing their username as a parameter.  For the privileges to work we need to store their username in the session ($_SESSION['l_user'] = $user).  Lastly, we redirect them to the first page you want them to see once logged in, which in this example is main.php.

If they are not a valid user then we would redirect them back to the login page with a message stating that fact.

Protect Pages


Now that the user is logged in we need a way to distinguish on each page if a valid user is logged in so they can view the page or redirect them to the login page if they are not.

checkLogin.php
————————————————————————-
<?php
//start the session
session_start();

//check to make sure the session variable is registered
if(session_is_registered(‘user’)){
//the session variable is registered, the user is allowed to see anything that follows
}
else{
//the session variable isn’t registered, send them back to the login page
header( “Location: index.php?error=You have to be logged in to view this website” );
}
?>
————————————————————————-

Firstly we need to have start_session() to ensure that we are working within the proper session, and then we check to see if the user is registered and if they are we allow them to view the page, otherwise we send them to the login page (index.php) and use the error variable, mentioned in index.php to display the message and have them login.  If you wish to add more functionality you could, upon having a successful login, have it redirect back to the page they were trying to access.

Remember, you have to include this page at the top of EVERY page you wish the user to be logged in to view, and it has to be the first thing (prior to any other code) so that it gets processed correctly.

Utilizing Permissions

I took advantage of the fact that a user was an admin or a guest by checking the permissions value of the current logged in user prior to displaying links to insert, delete, or update records within the database.  If the check came back that they were an admin I would provide them with a link, otherwise I would place nothing making my code something like:

<?php
$user = $_SESSION['l_user'];
if(isAdmin($user))
echo "<p><a href='inserthuman.php'>New Record</a></p>";
?>

Logout

Lastly, now that we have a logged in user, we need a way to log them out and end their session, so that if they (or another user) try to access any pages login credentials will need to be provided.

logout.php
————————————————————————-
<?php
//start the session
session_start();

//brute force it… destroy it all… because checks were not working
session_unregister(‘user’);
session_unset();
session_destroy();
$_SESSION = array();

header( “Location: index.php?error=You have successfully logged out” );

?>
————————————————————————-

Again we need to make sure that we are working within the correct session (session_start()).  First you need to unregister the user and destroy the session.  Afterwords, to really make it work, I found that I needed to destroy all data in the $_SESSION variable, so I destroyed its current contents by reassigning a new empty array to the variable.

Lastly, now that we have taken care of the session we will redirect them back to the login screen stating that they are successfully signed out.

Conclusion

With these elements all put in place I was able to create a successful login system for my database front-end.  It does not do anything fancy, like allow for administering user accounts, setting permissions (beyond the basic ADMIN or GUEST), etc. but this could be expanded to incorporate some advanced functions if necessary.

Phone System Database: The Beginnings

Saturday, May 29, 2010 17:05
Posted in category: Projects>Personal>Databases

Overview 

Starting last summer I have been assisting with the VoIP roll-out.  I am now back for another summer and have obtained a project that has the potential to be exciting and a learning experience, which enhances the working experience.  Learning does not stop when you leave the classroom, but picks up and becomes more exciting as you embark are interesting (though not always) projects. 

My task is to design and implement a database which can be used to store data relevant to our phone system infrastructure of production units and not an inventory system.  This will include appropriate server and switch information, phone and fax line information as well as a place to make comments that are dated to keep track of changes or other meaningful information related to a particular phone system. 

For this project I am using an Apache webserver, MySQL 5.0 for the database running on Linux (CentOS 5.4) and MySQL Workbench to create a preliminary Enhanced Entity Relationship Diagram (EERD). 

It is necessary to start with a logical representation of your database before moving on to the physical representation unless you are 100% confident when to use a natural or surrogate primary key, foreign keys, and composite keys within your tables.  I suggest always starting with a logical model because this allows you to normalize and potentially catch any glaring design flaws or oversights. 

Phase 1: The Design 

 

Phone System Database EERD

Figure 1: Phone System Database EERD

Naming Conventions

You should decide on a naming standard to implement across the database for your tables and there columns.  This keeps things consistent and makes it easier for future individuals to follow.  Typical naming schemes are all lower case using an underscore to separate words (i.e.: phone_system) or to capitalize the first letter of each word (i.e.: PhoneSystem). 

Natural or Surrogate Primary Keys? 

When researching this topic there appears to be valid reasoning for using a natural primary key (PK) (a column storing application data that will always be unique per entry) over a surrogate key (not derived from application data but will act as the unique identifier), which typically is an auto-incremented integer. 

I went with surrogate keys throughout because of the processing time required for queries to compare strings of varying lengths and greater than five or my table did not include any other unique column.  If tables exist where a natural key can be justified then do so as you do not need to use one method exclusively (which is impractical) within a database.  As an example for a customer table you could use a customer number or social insurance numbers as the PK, whereas in an address table  you would have to use multiple (or all) columns to create a unique primary key making a surrogate key more reasonable. 

When using surrogate keys as your primary keys, they should be of type integer and automatically incremented to insure uniqueness by allowing the PKs to be handled by the DBMS. 

Identifying or Non-Identifying Relationships? 

Non-identifying relationships (represented by dotted lines in the EERD) do not enforce data integrity and uses the primary key of one table as the foreign key in the other.  In a case where it is a one-to-many non-identifying relationship the primary key on the one side becomes the foreign key of the table on the many side.  I use this type most often as there is no direct dependency on the foreign table. 

Identifying relationships (represented by solid lines in the EERD) lead to composite primary keys and can lead to a composite key spanning six or seven columns, which can become very messy for coding so I use them cautiously.  You should only use this relationship when your table requires the identifying relationship (hence the name) as part of its identity.  That is when the information from the other table is required as part of the entity.  In my case, I chose to make the relationships from the manu_model table identifying because every table it relates to requires/has a manufacturer and model. 

Database Engine 

The database engine (or “storage engine”) is set for each table either manually or by using the default storage engine, typically MyISAM for MySQL.  The database engine is the underlying software component that a database management system (DBMS) uses to create, delete, retrieve, and update data from a database.  This option affects things such as performance and data consistency. 

Briefly, InnoDB is ACID compliant, fast for updating and uses row level locks making it suitable for transactions, whereas MyISAM is fast for reading and inserting using table level locks which make it impractical for transactions.  InnoDB allows cascading deletes/updates whereas stored procedures or code you have written is required for MyISAM, making it ideal to use InnoDB for some tables while using MyISAM for others. 

You are able to change from one MySQL storage engine to another, which is a nice feature, if it is unavoidable.  This can be done using the ALTER TABLE statement via the mysql> directly on the server, through ssh or via phpMyAdmin. 

Example 1: 

ALTER TABLE myTable ENGINE = MYISAM; 

ALTER TABLE myTable TYPE = INNODB; 

The statements in Example 1 would change your MySQL database engine from MyISAM to InnoDB.  When considering a change you have to ensure it is necessary because converting large tables between engine types takes a lot of computer resources for large tables.  This is where you hope good planning from the beginning will pay off and you start with the most appropriate table type. 

For other database engine types and further information check out http://dev.mysql.com/doc/refman/5.0/en/storage-engines.html (change versions if necessary). 

Views 

In figure 1, you can see a bunch of views that I have created (as named yellow ‘ovals’), which allow me to gather data from multiple tables into one place for easy viewing and updating of relevant information based on the criteria I specify in my SQL statements, and give the columns easier to read and understand names when necessary.  As an example: 

CREATE VIEW `phsysdb`.`tower_info` AS 

SELECT srv_name AS 'Server_Name', manufacturer AS 'Manufacturer', model AS 'Model', ram_gb AS 'RAM (GB)',  cpu_speed AS 'CPU Speed', num_processors AS '# of Processors', num_power_supplies AS '# of Power Supplies' 

FROM phone_system PS, hardware H, manu_model M 

WHERE PS.ph_system_id = H.ph_system_id AND M.manu_model_id = H.manu_model_id 

ORDER BY srv_name; 

Creates the view tower_info which shows relevant columns from the ph_system, manu_model, and hardware tables based on the equality of the primary/foreign key pair to match the data correctly and then ordered by the server name. 

Finalizing the Design 

Once you have your logical design completed you should perform some tests by inserting some data into the tables.  Make sure that each column is storing only one thing and should not be broken into two or more columns and that each table is only representing one entity.  Essentially you will want to perform the process of database normalization. 

Conclusion 

Now that I have completed my logical model (Phase 1) it is time to move on to Phase 2 (Logical to Physical), which is to create the physical model. 

Phase 2: Logical to Physical 

Now that I have a logical representation you need to make it become a reality.  If you are using MySQL Workbench than you can connect to your database server via Database -> Synchronize Model and your schema name should match up with the database you created on the server if you have already. 

The way that worked best for me, as it gives you a better idea of errors, and made it easier for me to debug my model is to get the SQL commands to execute yourself on the server.  This is done via Database -> Forward Engineer, select the objects you wish to include, and then in the review phase you can save the script to a .sql file.  Once you upload the .sql file, execute it on your server, within the directory the file resides, with the command: 

mysql --user=username --pass=password database_name < filename.sql 

If the design of your database (and SQL statements) are syntactically correct there will be no errors, otherwise, you will have to check into the errors and correct your model accordingly and repeat Phase 2.  If you have phpMyAdmin installed it allows you to import your database using a GUI. 

If you wish to go into greater depth you can design and write the SQL statements yourself to create your tables. 

Conclusion 

Now that I have completed Phase 2, and have all our tables stored in the database, I need some way of managing the data (from an end-users perspective).  This will be done in Phase 3 by creating my own front-end, or finding an open-source project that I can use and modify to my liking. In my case I want it to be web based. 

Two and a Half Men

Friday, May 14, 2010 20:20
Posted in category: News>Tube Inspired

Television (TV) is a very relaxing past-time for me. :D   I love to have the TV on while I am doing some work (except studying for an exam/test), especially if it is programming or something casual.  When I can on a Monday night and a new episode of Two and Half Men is on, I am watching and having a good laugh because it doesn’t disappoint.

Two and a Half Men seemed to be one of those TV shows you either loved or you hated.  It premiered back in 2003, though I never seen it for the first time until a few years later, and sparked an instant love of the show within me.

The comical adventures coupled with quick, witty comebacks made for a very entertaining half hour leaving you wanting more.  Jake, played by Angus T. Jones, is a very ‘stunned’ child on the show, which I interpret as just pure brilliance.  Charlie Sheen plays his character ‘perfectly’, and perhaps in light of what’s transpired in the media a little too well.   It is definitely unfortunate and I am trying not to pass any judgment/bias.  I would love to see him pass through the divorce, custody hearings, etc. and still be able to continue being part of the show so that it can continue to bring entertainment into the homes of many.  Unfortunately, not everyone will see things this way, as why should a series be discontinued because of an actors personal matters, if he can still perform??  Yes, if he is locked up somewhere then it would definitely be difficult, but otherwise I know I am able to separate between his professional and his personal life (which really isn’t any of my business), just like the rest of us should be trying to do in our own lives.

In summary, the tag-line, “Two adults. One kid. No grown-ups.” says it all.  The combination of cast, writers, etc. brought life to the TV with pure genius.  I will be sad to see Two and a Half Men leave the air, but I will try to treasure the laughs brought into my living room while watching.  I am sure there’s more I could say, but I have got it off my chest and would be interested to hear what others have to say.

New Page: Docs & Downloads

Monday, December 28, 2009 17:00
Posted in category: News>ForeverOdd.com

I decided a couple days ago that it was time to accumulate all my software releases into a central location where people can go to scan all the possibilities and download anything they would like to use.  It contains the name of the software package, a brief description of what it is with a link to the post(s) that tells more details, etc.  They are grouped into two tables sorted aplhabetically by name, then version.  The first table is for all the latest releases and the second for all previous releases.

This page will be updated whenever a new public release of my software programs comes to life.

The page can be accessed by clicking on the Docs & Downloads tab at the top of the website or here.

Card Deck Version 0.5

Monday, December 28, 2009 16:50

I got the urge to do some programming over the holidays and since one of my ideas was for a card game I thought I would create a deck of regular playing cards that could be used for playing any card game which uses a regular deck. Basically the deck includes all 52 cards plus 2 jokers, however how many jokers are active in the deck depends on how you initialize your deck of cards, with a integer between 0 and 2.

Since I was uncertain as to which game I would like to start with I decided to just do an individual package for the card deck which I the packaged into a jar file and can use that in a resource for my other applications. I have attached the jar file to this post for others wishinig to use this card deck for there own java applications. It contains six basic card back designs which can be used plus the acutal card faces.

Note that I have not actually tested this package yet, hence it is Version 0.5. If you happen to use this package and find bugs or updates you think might be nice, please let me know and I will do my best to implement those if I see fit. I am hoping to move on to creating my own card game using this package and thus will see how it works myself. I will update if I find anything.

Card Deck UML Diagram v 0.5

Card Deck UML Diagram v 0.5

You can view the documentation by accessing the documentation section and choosing Card Deck JavaDoc.

Download: Card Deck (jar)

Edit (Jan 3 @ 8:59PM): Updated the UML diagram to show parameters along with attribute & return types.

WP Page Layout & Text Updates

Sunday, December 27, 2009 0:43

If you were surfing my site today you may have noticed that the look and feel of the site was changing frequently.  This was in preperation for another page on my website.  Today I decided it was time to change the layout of my WP pages a bit to make more room.  Thus I took out the entire sidebar and doubled the width.  I had to photoshop the bottom and top borders to fit the new size, and thus update the CSS to accomidate the new images and formatting.  I then had to update the page template (page.php) file to point to the new CSS code I added.  I couldn’t just replace the old information with the same tag names as I still wanted the posts to keep the previous formating.

For quite some time now I have always wondered if the text on my site was to lite for comfortable reading.  Now I never had any complaints from readers, but then again, perhaps no one reads long enough to care or just didn’t want to take the time… lol.  Quite alright as this is all about being a learning experience for me.  I darkened the text, from my perspective, to make it easier to read.  I didn’t darken the text for the tabbed content as much as I feel it is a secondary section of my website.  Some may not agree, and if you would like that text to be darker please let me know. I also darkened the text (a shade between the previous too) for the undisplayed pages in the navigation across the top.

Download: green-dream 1.4

Maze Solver Game

Saturday, December 19, 2009 15:43

Essentially what the game consists of is you enter the size of your maze as an integer n (ie: 10) and then it generates a random maze of size nxn (ie: 10×10) which can be different for each nxn matrix you generate. Do to time restraints I wasn’t able to implement the A* search like I wanted to so I did it recursively. The downfall for this is that for a maze 29×29 or greater it may or may not work depending on how fast it finds the end point. This is because the stack is not big enough so you get a stack overflow error. Just the same it was an interesting project. Give it a try if you like.

Screenshots:

Freshly generated maze

Freshly generated maze

Solved maze.

Solved maze.

 

Note that since this is a school project nothing beyond the requirements was added (hence no About section or anything like that).

Windows (all): Maze (exe)
Linux (right click and open with Java): Maze (jar)
Mac users should be able to use the same as Linux.

Windows users can use the jar version too if they prefer. When downloading the jar version, make sure it has the extension .jar (ie: in windows may try to download as .zip, replace zip with jar).

Parsing XML

Saturday, December 19, 2009 14:34

For one of my classes a project was to write two programs, one of which uses the document object model (DOM) API to parse an XML file and one which uses the Simple API for XML (SAX) API.  The programs are just tiny and do not dod anything fancy.  Basically just breaks down the content of the XML files into the elements, attributes, and content then displaying them in a very primative GUI.

Note that since this is a school project nothing beyond the requirements was added (hence no About section or anything like that).

Windows (all): DOM XML (exe), SAX XML (exe)
Linux (right click and open with Java): DOM XML (jar), SAX XML (jar)
Mac users should be able to use the same as Linux.

Windows users can use the jar version too if they prefer. When downloading the jar version, make sure it has the extension .jar (ie: in windows may try to download as .zip, replace zip with jar).

Pathfinder: A path finding game.

Friday, October 30, 2009 17:56

Pathfinder is all about finding a path between point A and point B.  The GUI portion, provided for us, is sectioned off into a grid of ‘tiny’ squares where two are colored turquoise (set by programmer), in my case one on the mid left and the other on the mid right side of the grid.  You start by clicking on squares filling them in to create lines/walls to make obstacles between the start and finish point.  Then once you are done with that you click ‘Find Path’ and the program searches for a path, if one is not found then you see nothing, otherwise if the algorithm was able to find a path the GUI is updated to display the path using green squares.

The following are screen shots of the program:

Squares filled in before clicking find path.

Squares filled in before clicking find path.Clicked 'Find Path' and the shortest path is shown in green.

Clicked 'Find Path' and the shortest path is shown in green.

Clicked 'Find Path' and the shortest path is shown in green.

When I started this project I first read through all the code provided to us and then once I figured I had a grasp of the code I decided to just dive in and start coding and within three hours I had a semi-working program.  I started with implementing the equals method and hashCode method in the Location class, which thankfully never had to be changed throughout my journey of re-implementations.

My first implementation was using vectors, which ”worked” but was very slow do to the seek times in finding the proper way points while performing certain functions.  I left it running over night just to see if the one case would ever solve, and it just seemed to sit there.  The program never crashed and when I checked my CPU usage it had sky rocketed.  I then decided that a 2D array would provide a constant seek time.  At first glance this appeared to work flawlessly; that is, until you try to find a path where none exists, then you get a lovely null pointer exception and the program crashes as it tries to find a path outside of its bounds.  I figured now would be a good time to give a thorough read of the assignment and I was more formally introduced to classes HashMap and HashSet which made my life a dream.  When applying this concept to storing way points as open or closed the program worked flawlessly.  The variable declarations are as follows:


/** Stores open way points **/
private HashMap<Location,Waypoint> openHashMap;
/** Stores closed way points **/
private HashMap<Location,Waypoint> closedHashMap;

Note that since this is a school project nothing beyond the requirements was added (hence no About section or anything like that).

Windows (all): Pathfinder (exe)
Linux (right click and open with Java): Pathfinder (jar)
Mac users should be able to use the same as Linux.

Windows users can use the jar version too if they prefer.  When downloading the jar version, make sure it has the extension .jar (ie: in windows may try to download as .zip, replace zip with jar).

Card Game(s)

Sunday, October 11, 2009 22:41
Posted in category: Projects>Ideas

This idea came to me one day while I was sitting in my math class waiting for it to start.  I had arrived quite early so I cracked out my PDA and started playing solitaire.  Then I got to thinking, wouldn’t it be neat to create my own card game in which I could make it 1, 2, 3 or perhaps even 4 players, depending on the card game I choose to implement.

With a multiple player card game I would want to implement artificial intelligence (AI), so that the user can choose to play by themselves against the computer or with friends.  The only problem with multiple human players is how I would prevent one player from seeing the other player’s hands.  I would have to set up some sort of system that allows them to toggle between views displaying the hands and hope that they play honest.  For added complexity one could allow for LAN/Internet play, which is something I wouldn’t mind trying to do, but definitely would add a whole new level of complexity as I would have to develop my own protocol, most likely. Even with a one player card game there is underlying logic/AI involved but not to the same degree as they are typically more ‘basic’ games.

I broke down the card games I am considering into two categories, ones which are played just with cards and ones that require a board of some sort for game play.

Card only games: Card games with board:
  • Auction (a.k.a. 120)
  • Crazy Eights (and/or countdown)
  • Go Fish
  • Solitaire (but that’s done quite a bit already)
  • Cribbage
  • Dirty Marbles
  • Sequence

 A few thoughts on ‘implementation’, that is how I am conceptualizing I’d actually accomplish a card game.  Any game I choose would require a GUI environment for game play.  In the case of the AI, I may have to add an attribute that weights the cards importance, that is which one would be of higher importance to play if it is a legal move.  How I would model the logic behind some of the more ‘complex’ strategy based card games, I am unsure, but that is what doing these projects are about for me, learning something new.

One last thing I am going to mention in this post, which could potentially change as this is just initial thinking, is that if I wanted to allow users to switch between different designs in decks of cards

I have discovered online that there are downloadable decks of cards, under open licensing, which I could potentially use.  That would probably be ideal for me as graphic design is definitely one of my weaker areas.