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

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

My spirit is with you walkah

But my body will have to miss drupalcon.

+1 for your core auth ideas.

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! :-)