This is a follow-up to my earlier post
in which I described a simple trick changing Drupal's password reset behavior. That trick emails the user a link that logs them directly into the website, instead of the default one-time login page. That one-time login page forces user to click a Log in
button before they are able to change their password.
In the thread following that original post, Heine
referred me to the Drupal issue in which the one-time login form was created
. Now I understand better the reasons behind the one-time login form. To be perfectly frank, the solution from that thread was lazy. It solved the problem, but not elegantly, and Drupal deserves better. The user asked to reset their password so that's the form they should see, as soon as possible without the unnecessary step.
Here's what the user sees first, in core Drupal:
And here's what (I think) they should see:
This post describes how to accomplish this with a custom module. [UPDATE
: Save yourself the trouble of writing a custom module by downloading Simple Password Reset module
Our strategy is to replace the unwanted behavior, which comes from a menu item defined in user.module. We use hook_menu_alter() to replace that behavior.
An access callback ensures that only users who received the password reset email can reset their password. The URL parameters have to be just right. This is the same logic used in the core Drupal function that renders the one-time login form.
Now that our access callback ensures only the right users can access our reset page, we can show the profile edit form. Remember, this is where Drupal shows the unwanted one-time login. Instead we let the user make the password change right away.
That seems quite simple, but we're not done. At this point the user would be able to change their password, but then they'd have to log in manually. We want to save them the trouble, and log them in right away. The profile edit form becomes the one-time login form
. To do this, we need a hook_form_alter().
Two things to note in the above code. First, we add a submit handler to the profile edit form (but only when used to reset a password). Our submit handler logs the user in so they don't have to do it manually.
Second thing to notice, we honor an optional parameter, "brief", which abbreviates the form. This is because Drupal uses the reset page not just when a password is reset but also when new user accounts are created or email addresses are confirmed. In those cases it may be reasonable to show the entire profile edit form. When just resetting password, it's nice to show them only that portion of the form. To use this feature, under Admin >> Configuration >> People >> Settings >> Password recovery, replace the token [user:one-time-login-url]
This technique allows an administrator to choose between the longer or shorter version of the form fairly easily.
So there you have it! This approach should have none of the drawbacks of my earlier trick, and all the benefits.