Software investigate

Use BrowserID for email address validation

If handling email address verification sounds like too much hard work, then BrowserID could be the registration solution that you are after.

In a previous article we looked at using Twitter to power our registration system, today we are going to add a new email authentication system from Mozilla called BrowserID.

To understand BrowserID, I'll quote the entirety of its Wikipedia entry:

A secure authentication mechanism prototyped by Mozilla.

A better explanation is given in the video below:

It's relatively early days for the system, with features still being added, but what drew me to it was its simplicity. That simplicity comes from its only usage being to validate email addresses, but if you wish to support the full gamut of registration options available, BrowserID will be one of the least painful systems you will add.

Starting with the code that we used for Twitter authentication last time, we will need to bring in two JavaScript libraries: BrowserID and jQuery. If you look at the implementation guide you'll see that the assertion needs to be verified against https://browserid.org/verify as a POST request, to accomplish this we will need to have jQuery pass the assertion over to a PHP script that will make the call for us --- because this makes use of AJAX, and I don't feel like coding an AJAX handler from first principles, we'll use jQuery.

I chose to use the Google-hosted jQuery library, which comes with its own differing nuances, but there's no reason not to use your own hosted library.

We need to add the following code to the head of our file.


<script src="https://browserid.org/include.js" type="text/javascript"></script>

<script type="text/javascript" src="https://www.google.com/jsapi"></script>

<script type="text/javascript">

google.load("jquery", "1.7.1");

function browserid_click(){

navigator.id.get( wantAssertion);

}

function wantAssertion(assertion) {

if (assertion) {

// This code will be invoked once the user has successfully

// selected an email address they control to sign in with.

$.post('/registr/browserid_assert.php', { assertion : assertion },

function(data){

var d = jQuery.parseJSON(data);

$("#reg_avatar").html( '<strong>Logged in as:</strong><br/>'+d.email );

fireAjaxUpdate(d.email);

}

);

} else {

// something went wrong! the user isn't logged in.

}

}

</script>

To get a BrowserID sign-in button, I've just used one of the images from the site, added an onclick property, and styled the cursor. I added the button into the div where the Twitter sign-in button appears.


<div id="reg_avatar"><span id="signin-btn">Loading ....</span>

<img src="browserid_sign_in_red.png" onclick="browserid_click()" style="cursor:pointer;"/>

</div>

Now to create the browserid_assert.php file that passes our assertion to https://browserid.org/verify and passes back the result. The only gotcha to be found here is to make sure that you turn the $post_vars array into a URL-encoded string via http_build_query, otherwise the verification will fail on browserid.org's end, as it will complain that the encoding is incorrect.


<?php

if($_POST['assertion']){

$page = 'https://browserid.org/verify';

$audience = "[YOUR IP/DOMAIN NAME HERE]";

$post_vars = array( 'assertion' => $_POST['assertion'], 'audience' => $audience );

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $page);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

curl_setopt($ch, CURLOPT_POST, true);

// We do http_build_query here as we need application/x-www-form-urlencoded encoding

// and curl only does this when presented with a string rather than an array

curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_vars));

$response = curl_exec($ch);

curl_close($ch);

echo $response;

}

else { echo '{"error": "go away"}';}

?>

Now we have a working version of our page with BrowserID providing a verified email address.

The usability can be improved by two additions. First by changing the browserid_click function to:

function browserid_click(){

navigator.id.get( wantAssertion, {allowPersistent: true});

}

and creating a function to silently check for a persistent log-in from BrowserID:

google.setOnLoadCallback(jqLoaded);

function jqLoaded(){

$(document).ready(function() {

navigator.id.get(wantAssertion, {silent: true});

});

}

In terms of functionality, we are now done with all that BrowserID can offer, and can forward the validated email address to a user database at our leisure.

About

Some would say that it is a long way from software engineering to journalism, others would correctly argue that it is a mere 10 metres according to the floor plan.During his first five years with CBS Interactive, Chris started his journalistic advent...

0 comments