Recent challenging task I received from BitterCoffee (BC) is to create a Single Sign On. Sounds simple but pretty challenging as the other host which provides another application have a totally different database structure. Login process will be done on BC’s site then users will click on a link to go to the other site.
Session will most likely not to work. I thought of using JSON but I failed to figure out how to make the Javascript to be dynamic as I always prefer to use jQuery (if you have an idea, feel free to share). In the end, I decided to use PHP along with MySQL and cURL.
We will first start by creating a table to handle the login session:
CREATE TABLE IF NOT EXISTS `sso_login` (`user_id` int(11) NOT NULL)
Purpose of the table is to store logged in users and remove then upon signing out.
Next is the PHP script which will insert new user id upon signing in (file name: register.php):
<?php
/**
*
* @author Mohd Rashidi Bin Mohd Zin ([email protected])
*/
$userId = $_GET['id'];
$sql = sprintf("INSERT INTO sso_login VALUES ('%s')", $userId);
mysql_query($sql);
?>
Simple, isn’t it? All it does is inserting the user id into the table.
Next is the file which delete the user id when user is signing out (file name: drop.php):
<?php
/**
*
* @author Mohd Rashidi Bin Mohd Zin ([email protected])
*/
$userId = $_GET['id'];
$sql = sprintf("DELETE FROM sso_login WHERE user_id = '%s'", $userId);
mysql_query($sql);
?>
I believe the script is pretty much self-explainatory.
Next is the file which checks whether user is already logged in or vice versa (file name: check.php):
<?php
/**
*
* @author Mohd Rashidi Bin Mohd Zin ([email protected])
*/
$userId = $_GET['userId'];
$sql = sprintf("SELECT COUNT(*) FROM sso_login WHERE user_id = '%s'", $userId);
$query = mysql_query($sql);
if (mysql_result($query, 0, 0) > 0)
{
echo 'User '.$userId.' has logged in';
}
else
{
echo 'User '.$userId.' is not logged in.';
}
?>
This script will check whether the user id being passed is available in the table or not. If not it means that the user have not logged in.
These three scripts will be store on the other party’s server. Next are scripts which will be store on BC’s server where the login and logout process being done. All these processes are using cURL.
First is the script which will update the other site when user is logged in (file name: login.php):
<?php
/**
*
* @author Mohd Rashidi Bin Mohd Zin ([email protected])
*/
if($_POST)
{
$username = $_POST['username'];
$password = $_POST['password'];
if (($username == "bcoffee") && ($password == "demo"))
{
$userId = 10;
$target_site = sprintf("http://the-other-site.com/register.php?id=%s", $userId);
$timeout = 5;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_site);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_exec($ch);
curl_close($ch);
header('location: index.php');
}
}
?>
You might notice that the username and password are hard coded, this was for P.O.C purpose, so it does not matter. Back to the tutorial.
As you can see, it will reach register.php with the user’s id. Refer back to content of register.php which will then insert the user id into the table. This way, the other server will know that user is already logged in.
Next is the script which will notify the other server when the user is signing out (file name: logout.php):
<?php
/**
*
* @author Mohd Rashidi Bin Mohd Zin ([email protected])
*/
$userId = 10;
$target_site = sprintf("http://the-other-site.com/drop.php?id=%s", $userId);
$timeout = 5;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_site);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_exec($ch);
curl_close($ch);
header('location: login.html');
?>
Similar to login.php but this time, it will remove the user id when user is signing out. Hence when the system checks (using check.php) and found that the user id is not available, it will know that the user is not currently logged in.
Please remember that in order to use this method, particular settings are required to enable cURL on your server.
Happy coding 😎