Best way for a ‘forgot password’ implementation?

authenticationforgot-passwordpasswordssecurity

I'm looking for the best method to implement a "forgot password" feature.

I come out with 2 ideas:

  1. When user click on forgot password, the user is required to key in the username, email and maybe date of birth or last name. Then a mail with temporary password will be sent to the user email account. The user uses the temporary password to login and resets his password.

  2. Similar, but the email would contain a link to let the user reset his password.

Or anyone can suggest me a better and secure way? I'm also thinking to send the temporary password or link, force the user to reset the password within 24 hour, or else the temporary password or link will not be usable. How to do that?

Best Solution

Update: revised in May 2013 for a better approach

  1. The user enters his username and hits "forgot password". I also recommend the option of entering the email address instead of the username, because usernames are sometimes forgotten too.
  2. The system has a table password_change_requests with the columns ID, Time and UserID. When the new user presses the button, a record is created in the table. The Time column contains the time when the user pressed the "Forgot Password" button. The ID is a string. A long random string is created (say, a GUID) and then hashed like a password (which is a separate topic in and of itself). This hash is then used as the 'ID' in the table.
  3. The system sends an email to the user which contains a link in it. The link also contains the original ID string (before the hashing). The link will be something like this: http://www.mysite.com/forgotpassword.jsp?ID=01234567890ABCDEF. The forgotpassword.jsp page should be able to retrieve the ID parameter. Sorry, I don't know Java, so I can't be more specific.
  4. When the user clicks the link in the email, he is moved to your page. The page retrieves the ID from the URL, hashes it again, and checks against the table. If such a record is there and is no more than, say, 24 hours old, the user is presented with the prompt to enter a new password.
  5. The user enters a new password, hits OK and everyone lives happily ever after... until next time!