In the past, authentication with a BYOND key was only possible if you used DMCGI to do it. There was simply no way to get the login details any other way. Some people have requested a new feature to allow any program to authenticate BYOND keys.
That feature might not be here, but I offer the next best thing: authentication using a mediator server (which is pretty much what the feature request suggests anyway, so I guess I did the work for them!).
Without further ado I would like to present:
The McKay-Carter Intergalactic Bridge dta_auth BYOND authentication system
Let's get on with the technical details, as I'm sure most of you are looking straight for it.
The following steps are taken to authenticate a user:
- The user arrives at http://www.yoursite.com/login.php.
- At this point your script redirects the user to http://home.androiddata.net/auth.cgi and passes along two variables:
- A session id which is a variable only your server and the real client share. Upon receival this is immediately taken out of the loop to minimize the possibility of eavesdropping. In my example it is derived from the current time.
- A return URL which is usually back to your script. In my example it will be http://www.yoursite.com/login.php.
- The user is taken to http://secure.byond.com where they can login..
- Once the user successfully logs in with a valid BYOND key they are redirected back to http://home.androiddata.net/auth.cgi where the magic happens.
- My script redirects the user back to http://www.yoursite.com/login.php where you receive a certificate ID. You then pass this value back and confirm the validity of the certificate, after which the authentication is completed.
The security measures taken:
- A unique ID pinpoints the exact certificate that contains the authentication request.
- A session ID verifies that the certificate was indeed requested by your server.
- A hash is sent with the client to ensure that they have access to that certificate and to ensure other domains can't read your certificates.
- The BYOND key and ckey are both stored in the certificate and cross-referenced with what you receive to prevent spoofing of keys.
- You may optionally specify an IP address (or other unique means of verification) to verify that as well.
- Finally, the certificate is destroyed immediately after you've checked it to prevent it from being re-used in the future.
In addition to the above clients are expected to always log-in with a new set of credentials, so it's not possible for a client to re-use someone else's log-in on your site.
And now a code sample (because nobody on BYOND listens to you unless you post one!):
index.php<?php session_start();
if(isset($_SESSION['byond_key'])){
echo 'You are logged in as ' . $_SESSION['byond_key'] . '! <a href="login.php?logout=1">Logout</a>';
}else{
echo 'You are NOT logged in. <a href="login.php">Login</a>';
}
?>
login.php
<?php session_start();
//the URL that the mediator server should reroute the user to once authentication finishes goes here
define('URL', 'http://www.cowed.org/auth/login.php');
if(!isset($_SESSION['byond_key'])){ //we are not logged in
if(isset($_GET['id']) && isset($_GET['key']) && isset($_GET['ckey']) && isset($_GET['hash'])){
//looks like we received a response
$crl = curl_init();
curl_setopt($crl, CURLOPT_URL, 'http://home.androiddata.net/auth.cgi?id=' . $_GET['id'] . '&sid=' . $_SESSION['sid'] . '&hash=' . $_GET['hash'] . '&ckey=' . $_GET['ckey'] . '&key=' . $_GET['key']);
curl_setopt($crl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($crl, CURLOPT_CONNECTTIMEOUT, 5);
$ret = curl_exec($crl);
curl_close($crl);
if($ret == 0){
$_SESSION['byond_key'] = $_GET['key'];
header('Location: index.php');
}else{
echo 'ERROR: Received return code ' . $ret . ' from the mediator server.';
}
}else{
//redirect the user to the mediator server
$_SESSION['sid'] = time();
header('Location: http://home.androiddata.net/auth.cgi?sid=' . $_SESSION['sid'] . '&returnurl=' . URL);
}
}else{
//we're already logged in, so continue unless explicitly instructed to logout
if(isset($_GET['logout'])){
$_SESSION = array();
session_destroy();
}
header('Location: index.php');
}
?>
Please note: The example requires that you have the "curl" extension installed for PHP and assumes an installation of PHP5.2 or higher. If it doesn't work for you try these instructions.
I hope that this web service will open up more BYOND-powered websites and services.
Thanks!
-D