Blitzed.org - Help - Services Authentication
Introduction
This page is intended to help those of you who have web sites related to your channels. If your channels have been in existence for any length of time, or are quite popular, then you may have collected various web resources such as channel quotes, a message board etc..
Sometimes you then want to restrict who can access these resources. The traditional way to do this has been to give every person a login and a password. This is tedious for you to manageand it is also Yet Another Password for your users to manage too.
At Blitzed we have overcome this problem by coming up with a scheme whereby you can let people log in using their Blitzed nickname and nickserv password. This scheme is secure; your site will never see the user's password, it will only be informed whether the user has entered the password correctly.
Please note, this page is only meant to be informational for those who are already familiar with web programming and want to adapt their existing sites to authenticate from our nick database. We do not have the resources to help you design your site from scratch or teach you a programming language such as PHP! "It works for us" is about the best warranty or guarantee you will get from us.
What We Offer
At this stage we only offer an interface for you to tell if people can identify to a valid Blitzed nickname - there is currently no means to check anything else such as if they are on your channel access list. We do plan to implement that at a later date, but for now you can either be content to allow all Blitzed users into these areas of your site, or else do your own further checking. This can be as simple as you keeping a file of nicknames that are allowed.
Here follows an example of how one such site, the #blitzed FAQ was modified to take advantage of this scheme. I will refer to the following terms in this example so that we do not get confused:
- Client
- The user who comes to your web site wanting to log in
- Server
- Your web server that is providing services for your users
- Blitzed
- Any Blitzed servers that are involved
Required Software
This example uses the following software on the server-side:
-
PHP
This example will use PHP for the example of what code is needed on the server-side, however all communication between the server and Blitzed is done over standard HTTP methods so you should be able to use anything you like here.
-
MySQL
The server-side will need some means to store state. This could be done in PHP sessions, in a flat file or in a disk database file like Berkely DB. In this case MySQL was chosen because the server already used MySQL.
Anyone who wishes to send examples of this using other languages and software on their side is welcome to do so, if they think it will be useful to someone else.
The Tutorial
1. Register with Blitzed
The very first thing your site must do is register with Blitzed that you wish to use our services interface. We need this to happen so that we can give your server a unique key - this is the only way that you and Blitzed can communicate and know that the other side is who they are expected to be.
To do this, please approach a member of the Blitzed Web Team. It's probably quickest if you just come to #help on the network and ask to speak to someone from the web team.
You need to give 4 pieces of information:
A password that is unique to the server
A URL on your server that holds the code that will deal with a new session being created. Don't worry about this yet. Just give something like http://your.server.example.com/newsess.php.
A URL on your server that holds the code that will actually check if a previously setup session still exists and is valid. AGain don't worry, just give something like http://your.server.example.com/auth.php.
A textual description of what your site is. This will be shown on Blitzed's login page. You must teach your users to only give their nickserv password on Blitzed's login page. For example, "The #blitzed FAQ"
That should be everything for that stage. Once you're sure the information has been recorded on Blitzed's side, you can continue.
2. Create the database table on your side
This example uses a table called "session" in the database "phpwiki". You can alter it to use whatever table you like, or a flat file if you like. This example assumes a table that looks like this:
mysql> show columns from session; +--------+-------------+------+-----+---------------------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------------------+-------+ | sessid | varchar(32) | | PRI | | | | nick | varchar(32) | YES | | NULL | | | time | datetime | | | 0000-00-00 00:00:00 | | +--------+-------------+------+-----+---------------------+-------+
3. Install the code on your side
Now you will need to get those two pieces of PHP running that we talked about before. Here they are:
newsess.php
<?php
$secret = "s3kr1t";
// You need to set $mysql_host, $mysql_user, $mysql_password yourself
$db = mysql_connect($mysql_host, $mysql_user, $mysql_password)
or die("Could not connect: " . mysql_error());
mysql_select_db('phpwiki', $db) or die ("Can't use phpwiki: " . mysql_error());
// This bit will abort the process here if the thing talking to us does not
// know our secret
if($_GET['secret'] != $secret)
die("The secret remains secret");
$res = mysql_query(sprintf("INSERT INTO session (`sessid`, `nick`, `time`) " .
"VALUES ('%s', '%s', NOW())", $_GET['sess'],
$_GET['nick']))
or die("Error: " . mysql_error());
?>
auth.php
<?php
// You need to set $mysql_host, $mysql_user, $mysql_password yourself
$db = mysql_connect($mysql_host, $mysql_user, $mysql_password)
or die("Could not connect: " . mysql_error());
mysql_select_db('phpwiki', $db) or die ("Can't use phpwiki: " . mysql_error());
// Check for this session in our table
$res = mysql_query(sprintf("SELECT nick FROM session WHERE sessid='%s'",
$_GET['sess']))
or die("Error: " . mysql_error());
// If it's there, they get a cookie and get redirected to the proper site,
// which checks for the cookie.
if ($row = mysql_fetch_row($res)) {
setcookie('sess', $_GET['sess'], time() + 21600, '/',
'.blitzed.eu.org');
header('Location: http://blitzed.eu.org/');
}
echo "It's broken!\n";
?>
4. Adapt your site to check for this cookie
Every (sensitive) page on your site will need to check for the presence of the above cookie as it loads, and if it is there, it needs to check the session table to see if it refers to a valid session (otherwise people could just go making up cookies). Here's an example from the #blitzed FAQ:
<?php
$valid = 0;
$faqsessid = mysql_escape_string($_COOKIE[sess]);
if ($faqsessid) {
// They have a session ID.
$db = mysql_connect($mysql_host, $mysql_user, $mysql_password)
or die("Could not connect: " . mysql_error());
mysql_select_db('phpwiki', $db)
or die ("Can't use phpwiki: " . mysql_error());
$mysql_res = mysql_query("SELECT nick FROM session " .
"WHERE sessid='$faqsessid'")
or die("mysql_error: " . mysql_error());
if (mysql_num_rows($mysql_res)) {
$mysql_row = mysql_fetch_row($mysql_res);
// They are who they say they are! Store their nick in
// $nick, don't forget you'll probably need to do
// "global $nick" to use it inside any other functions
// later.
$nick = $mysql_row[0];
// Update the time so that it counts from their last page
// view.
mysql_query("UPDATE session SET time=NOW() WHERE sessid='$faqsessid'");
$valid = 1;
}
}
// If they gave a cookie with a session ID that wasn't present it isn't
// necessarily malicious; it could have just timed out. Send them back to
// the login page.
if (!$valid) {
header("Location: http://www.blitzed.org/login/?site=hashblitzedfaq");
echo "Redirect to login page.";
exit;
}
?>
5. Extras
Once you have customised the above code to your needs, you should have a way to make visitors to your website authenticate themselves against. Here are some other things you might wish to add.
A "logout" link
To log someone out of your site all you need to do is delete the relevant row in your session table. Execute the folowing MySQL query:
mysql_query("DELETE FROM session WHERE nick='$nick'")
or die("mysql_error: " . mysql_error());