Defaulting to OpenID on Drupal 5

Kudos to walkah et al for their work on the Drupal OpenID module and getting OpenID into core for Drupal 6!

By default, OpenID in Drupal 5 and 6 defaults to present regular Drupal authentication first, giving the user the option to toggle to authenticate via OpenID.

That's the exact opposite of what I wanted to deploy on my blog: I want users to log in using OpenID unless they have a very good reason not to. Here's how I solved the problem in 5 easy steps using just the magic of a phptemplate theme to modify the authentication interfaces to default to OpenID.

Step 1: Override Authentication UI

First I added the following overrides in my theme's template.php file to specifiy that I would be overriding various interface elements.

// override the user log in form at /user
function phptemplate_user_login($form) {
return _phptemplate_callback('user_login', array('form' => $form));
}

// override the user registration form at /user/register
function phptemplate_user_register($form) {
return _phptemplate_callback('user_register', array('form' => $form));
}

// override the password reset form at /user/password
function phptemplate_user_pass($form) {
return _phptemplate_callback('user_pass', array('form' => $form));
}

// override the user log in block
function phptemplate_user_login_block($form) {
// show hint in form element
$form['openid_url']['#value'] = 'OpenID Login';
// remove hint in form element on focus
$form['openid_url']['#attributes'] = array('onfocus' => "javascript:openid_url.value=''");
return _phptemplate_callback('user_login_block', array('form' => $form));
}

Step 2: New User Log In Template

Next I added a template file to my theme directory called "user_login.tpl.php" as per my override in template.php above with the following code.

// reverse default form element visibility toggles set in openid module js
drupal_add_js('$(document).ready(function(){$("#edit-openid-url-wrapper").show();$("#edit-name-wrapper").hide();$("#edit-pass-wrapper").hide();$("a.openid-link").hide();$("a.user-link").show();});', 'inline');

// render login form
print(drupal_render($form));

Step 3: New User Registration Template

Next I added a template file to my theme directory called "user_register.tpl.php" as per my override in template.php above with the following message, giving a link for users to go get an OpenID because I don't want users to create local Drupal identities.

Establish your <a href="http://openid.net/" title="Learn More about OpenID">OpenID</a> with a provider like <a href="http://myopenid.com/" title="Visit MyOpenID.com">MyOpenId.com</a>. Then come back to this site and <a href="/user" title="Log in to this site">log in</a> with your new OpenID.

Step 4: New Password Recovery Template

Next I added a template file to my theme directory called "user_pass.tpl.php" as per my override in template.php above with the following message, giving a link for users to go recover their password from their OpenID provider.

Visit your <a href="http://openid.net/" title="Learn More about OpenID">OpenID</a> provider to recover your password. Then come back to this site and <a href="user" title="Log in to this site">log in</a> with your OpenID.

Step 5: New User Log In Block Template

Next I added a template file to my theme directory called "user_login_block.tpl.php" as per my override in template.php above with the following code.

// reverse default form element visibility toggles set in openid module javascript
drupal_add_js('$(document).ready(function(){$("#edit-openid-url-wrapper").show();$("#edit-name-wrapper").hide();$("#edit-pass-wrapper").hide
();$("a.openid-link").hide();$("a.user-link").show();});', 'inline');

// render select elements in login block
print(drupal_render($form['form_id']));
print(drupal_render($form['openid_url']));
print(drupal_render($form['submit']));

You're Done!

After these 5 steps, users are presented with OpenID authentication on my site and guided to getting an OpenID if they don't have one already. A user with a local, Drupal identity can still toggle to authenticate on the now obscured /user login form, but only an existing user with the proper access can create new local Drupal users.

My dream for OpenID in Drupal core is to have admin UI that allows various configurations which make any necessary changes to the user authentication UI:

  • prefer OpenID authentication, allow Drupal
  • prefer Drupal authentication, allow OpenID
  • allow only OpenID authentication
  • allow only Drupal authentication (this case would be covered by just not enabling the OpenID module)

Let me know if you have more questions about or suggestions for this solution.

Comments

Changes to core authentication

This kind of change to core's authentication handling (preferring certain authentication schemes, disabling some, etc etc) is excactly the kind of stuff I want to discuss in my session at DrupalCon ( http://boston2008.drupalcon.org/session/openid-and-identity-drupal-futur... ) and work on for D7.

Great workaround for now though! :-)

My spirit is with you walkah

But my body will have to miss drupalcon.

+1 for your core auth ideas.

Make a module for D6

I think a module could make these changes for D6. If you add one more feature, I think it will be a hit. I want to default to whatever login mechanism the user last used on my site. So, storethat in a cookie and make the site react to the cookie. If the user last logged in via OpenID, show the OpenID form.

I wonder if some clever jquery that runs onload would be simpler than the procedure you describe here. Just simulate the click for 'login with open id'.

-moshe weitzman

is it relevant which OPEN-ID

is it relevant which OPEN-ID provider the user had chosen to use with drupal 6?

No, the user's OpenID

No, the user's OpenID provider shouldn't matter...that's the whole point of OpenID! ;)

What version of Drupal,

What version of Drupal, JQuery, and OpenID did you get this going with?

With the latest versions of everything, OpenID is simply not working. Multiple users have reported a problem:
http://drupal.org/node/378178

Nate have you seen this?

Sorry, since I upgraded my

Sorry, since I upgraded my site to Drupal 6 I haven't tried to redo this process and I don't remember which version of Drupal 5 or the OpenID module I first used. I always used whatever jQuery came stock with the Drupal release and try to stay current on Drupal releases, so I'm thinking it was working with fairly late versions of Drupal 5.

OpenID rocks! Thanks for the

OpenID rocks! Thanks for the comprehensive tutorial, xolotl. Added it to my bookmarks to use later.

Is there an update for this

Is there an update for this process for D6? or will this same process work?

Sorry, I haven't had a chance

Sorry, I haven't had a chance to update the process since I moved to Drupal 6. However, because the OpenID module works in the same basic way and theme templating is similar, the same basic strategy should work. There may need to be adjustments to the exact template names, form element names, etc to account for changes in D6. Post back here if you have success and or other questions!

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <img> <div> <br> <span>
  • Lines and paragraphs break automatically.

More information about formatting options

Mollom CAPTCHA (play audio CAPTCHA)
Type the characters you see in the picture above; if you can't read them, submit the form and a new image will be generated. Not case sensitive.