Dec
22
Written by:
Dylan Barber
12/22/2009 12:51 AM
One of the aspects I really like in Stackoverflow is that it uses OpenID. Now a lot of sites use OpenID already but none have made it as easy as Stackoverflow has. This really should be viewed as a model to get larger adoption of the OpenID standard across the web.
What’s so great about it? Well the Stackoverflow site has used images of the big OpenID providers clear (Goolge, Yahoo, AOL, myOpenID) then a lot of the the lesser ones that are used a lot (Live Journal, Wordpress, Blogger ,etc..). Simply click an icon or image and Stackoverflow uses a little jquery to try and log you in or ask you for the username at that OpenId provider. Many sites and the DNN provider included simply present the user with a field to paste in the url of the OpenId provider. Not a problem, but not every user on the web knows what that url is or where to find it.
My first project to make my site operate like Stackoverflow is going to be to add so enhancements to the default OpenID provider built by the DNN core group. Maybe in time they will adopt this into the code (here's hoping anyway).
So looking at how this should be done I came up with this:
- Create an array of the providers you want to use – for each one I need to include the:
- Name
- URL
- The label if a username is needed
- Picture or logo of the provider
So in a javascript file I am going to set up the first array like so:
var providers_array = {
google: {
name: 'Google',
url: 'https://www.google.com/accounts/o8/id'
},
yahoo: {
name: 'Yahoo',
url: 'http://yahoo.com/'
},
aol: {
name: 'AOL',
label: 'Enter your AOL screenname.',
url: 'http://openid.aol.com/{username}'
},
myopenid: {
name: 'MyOpenID',
label: 'Enter your MyOpenID username.',
url: 'http://{username}.myopenid.com/'
}
livejournal: {
name: 'LiveJournal',
label: 'Enter your Livejournal username.',
url: 'http://{username}.livejournal.com/'
},
wordpress: {
name: 'Wordpress',
label: 'Enter your Wordpress.com username.',
url: 'http://{username}.wordpress.com/'
},
blogger: {
name: 'Blogger',
label: 'Your Blogger account',
url: 'http://{username}.blogspot.com/'
},
verisign: {
name: 'Verisign',
label: 'Your Verisign username',
url: 'http://{username}.pip.verisignlabs.com/'
},
claimid: {
name: 'ClaimID',
label: 'Your ClaimID username',
url: 'http://openid.claimid.com/{username}'
},
clickpass: {
name: 'ClickPass',
label: 'Your ClickPass username',
url: 'http://clickpass.com/public/{username}'
}
};
The next part will be to provide the right URL to the field – and if needed wait for a username or submit the form if one is not needed.
That jQuery will look like this:
var providers = $.extend({}, providers_array);
var openid = {
cookie_expires: 6 * 30, // 6 months.
cookie_name: 'openid_provider',
cookie_path: '/',
img_path: 'http://sstatic.net/so/Img/openid/',
input_id: null,
provider_url: null,
init: function(input_id) {
// turn off hourglass
$('body').css('cursor', 'default');
$('#openid_submit').css('cursor', 'default');
// enable submit button on form
$('input[type=submit]').removeAttr('disabled');
var openid_btns = $('#openid_btns');
this.input_id = input_id;
$('#openid_choice').show();
$('#openid_input_area').empty();
// add box for each provider
for (id in providers_large) {
openid_btns.append(this.getBoxHTML(providers_large[id], 'large', '.png'));
}
if (providers_small) {
openid_btns.append('<br>');
for (id in providers_small) {
openid_btns.append(this.getBoxHTML(providers_small[id], 'small', '.png'));
}
}
$('#openid_form').submit(this.submitx);
},
getBoxHTML: function(provider, box_size, image_ext) {
var box_id = provider["name"].toLowerCase();
return '<a title="' + provider["name"] + '" href="javascript: openid.signin(\'' + box_id + '\');"' +
' style="background: #FFF url(' + this.img_path + box_id + image_ext + ') no-repeat center center" ' +
'class="' + box_id + ' openid_' + box_size + '_btn"></a>';
},
/* provider image click */
signin: function(box_id, onload) {
var provider = providers[box_id];
if (!provider) { return; }
this.highlight(box_id);
if (box_id == 'openid') {
$('#openid_input_area').empty();
this.setOpenIdUrl("");
$("#openid_identifier").focus();
return;
}
// prompt user for input?
if (provider['label']) {
this.useInputBox(provider);
this.provider_url = provider['url'];
} else {
$('.' + box_id).css('cursor', 'wait');
this.setOpenIdUrl(provider['url']);
this.provider_url = null;
if (!onload) {
$('#openid_form').submit();
}
}
},
/* Sign-in button click */
submitx: function() {
if ($('#openid_username').val() == "") return true;
// set up hourglass on body
$('body').css('cursor', 'wait');
$('#openid_submit').css('cursor', 'wait');
// disable submit button on form
$('input[type=submit]', this).attr('disabled', 'disabled');
var url = openid.provider_url;
if (url) {
url = url.replace('{username}', $('#openid_username').val());
openid.setOpenIdUrl(url);
}
return true;
},
setOpenIdUrl: function(url) {
var hidden = $('#' + this.input_id);
hidden.val(url);
},
highlight: function(box_id) {
// remove previous highlight.
var highlight = $('#openid_highlight');
if (highlight) {
highlight.replaceWith($('#openid_highlight a')[0]);
}
// add new highlight.
$('.' + box_id).wrap('<div id="openid_highlight"></div>');
},
useInputBox: function(provider) {
var input_area = $('#openid_input_area');
var html = '';
var id = 'openid_username';
var value = '';
var label = provider['label'];
var style = '';
if (label) {
html = '<p>' + label + '</p>';
}
html += '<input id="' + id + '" type="text" style="' + style + '" name="' + id + '" value="' + value + '" />' +
'<input id="openid_submit" type="submit" value="Sign-In"/>';
input_area.empty();
input_area.append(html);
$('#' + id).focus();
}
};
Next blog post will be to bring this together with the DNN OpenID provider.
Please note I didnot write the original jQuery code but I will be integrating it into the DNN OpenID provider.