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.
Is there an update for this process for D6? or will this same process work?
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!
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 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.
is it relevant which OPEN-ID provider the user had chosen to use with drupal 6?
No, the user’s OpenID provider shouldn’t matter…that’s the whole point of OpenID! ;)2009-04-08 08:35 -0700
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
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-future-usermodule ) and work on for D7.
Great workaround for now though! :-)
But my body will have to miss drupalcon.
+1 for your core auth ideas.