Implementing "Remember Me"/"Forgotten Password" Functionality
Assuming you don't store plain text passwords in the database (you DON'T store plain text password in the database - do you?!), you need to find a mechanism for allowing users to handle forgotten password. Typically I've seen two approaches - the "secret questions" and the "email me something".
I'll say right upfront that I REALLY don't love secret questions. Whether they're fixed or I can write them myself, they often aren't very secret (how hard is it to find out someones mothers maiden name? I can get that in 5 minutes in a bar.), frequently aren't relevant, and with free text input, are very easy to get wrong. I'm sure they serve a purpose, but I'd really like to hear some input from someone who DOES prefer these to an email based solution clarifying what they like about the approach and how they come up with questions that are genuinely secret and also universally applicable.
Of course, "email me something" isn't a perfect solution. If someone has hacked your GMail or your PC you are in trouble. There is also the wait for the email to go out (PLEASE use a different mail server for these emails than you use for the bulk mailings - I don't want to be waiting for email 3,000,000,001 in the queue!). That said, it seems to me the least bad approach. However, if you are going to use an "email me" approach, the question is what exactly you should email them and how you should track it.
It seems to me an easy solution is to create a UUID and store it in the users record. Then send them a link something like htttp://www.myco.com/login.html?action=resetpassword&email=test@test.com&UUID=xxxx-xxxx-xxxx-xxxx. When they go to that page, if the UUID matches the email address, you allow them to reset their password and then delete the UUID from their user record. Note I'm sending both the email and the UUID so I can't just randomly keep sending UUID's until I get to reset SOMEONE's password (not a biggie, but why not . . . ?). Also note that if someone clicks the "forgotten password" button twice, they will HAVE to use the second email (the second UUID will overwrite the first one) which I think is fine, and much better than a check for "but you already HAVE an outstanding email" which would put them SOL if they had deleted or lost the previous reset email.
Anyone doing anything different? Any subtleties I should be considering?



2.) Put in email.
3.) System checks to see if you have one or more accounts.
4) If one account - it locks the account (so they can't log in) and go to 6.
5) If multiple accounts, ask user to input username. Lock the account (so they can't log in).
6.) Generate new random temporary password and email it along with a special URL for unlocking account.
If password is correct and account is unlocked via correct URL, then... everything is great. Force them to change their password upon logging in. Otherwise, their account is locked and if something has gone terribly wrong, then they need to contact us and get the issue resolved.
1. click lost password link
2. ask secret question (to help confirm it is genuine user)
3. continue with rest of password process
while this might seem like you are adding more complexity for the user just for the sake of it. i think it's a good idea trying to prove that the person is who they say they are before you even think of creating an opening in the security of your site (i.e. messing about with user authentication), if it's the real user he'll know his answer so you can assume it is probably likely it's him or at least if it isn't then the person who knows the answer would also need to get into his email account before he can compromise his login. it also stops people maliciously changing other peoples passwords (if you are automatically trashing the old password when you generate the new one) by repeatedly requesting a new password on the account with the intention of causing them a nuisance.
you are of course absolutely right that secret questions are in no way secure (when pushed to use one i have a special password that i put in which has no relevance to the actual question and would only ever be known by myself) but when used in conjunction with other measures it can help prevent someone getting into their account as easily.
Furthermore, at this point, everything is being logged and if there are further issues, then we pro-actively get involved as all good people should. If someone is maliciously locking someone out, then so be it. No one is getting in the owner's account and we'll make further recommendations to the account owner going as far as suggesting that they start using a different email, changing usernames, etc. I'd rather be pro-active on security that to assume that everything is ok.
My security also has a bad password lockout system that if you use a bad password on a known account too many times, it'll lock you out with a time-lock. After time has elapsed, you can attempt to log in again. Otherwise, the time lock continues to get longer. After a threshold is met, notifications start going out to the appropriate party, etc.
The system can also keep track of the user's nth password (site configurable) and track the last nth password that you've used and basically forbid you from reusing passwords again until a criteria has been met.
Call me paranoid. I'd rather be safe than sorry, even if it is at the user's expense of being slightly inconvenienced.
If, however, you wanted to keep malicious changing-other-people's-passwords from happening, you could just create a second password field on the user record, and store the system-generated password in that. Then write your login to accept either the generated password, or the one chosen by the user. That effectively doubles your chances of brute-forcing your way in, but maybe 2 chances out of 32,000,000 is still acceptable odds.
If they forget their username or password they would select "forgot my password". From there they would enter their email and answer their security question. Their password is then reset and emailed to their email address.
Once logged in they can change their password.
1) click 'forgot' link
2) enter email & submit
3) (on good submit) send email to user with LINK (email address or username & generate UUID for link)to click to change password. Password is not changed at this time and account not locked. This way, other people can not interrupt service.
4) if linked clicked from email, and UUID & email or username match DB, send NEW password (random, six char alpha numeric) to the user.
5) delete UUIDs
A) the instructions and wording in the Emails MUST be very clear, and concise.
B) users can NOT interrupt another users service by locking account, etc..
I think the "secret question" is a good additional layer of security for apps that need it (e.g. online banking). Other than that, it seems to me that the basic approach of emailing a link that allows the user to change their password makes the most sense most of the time. It avoids the problem of being able to lock out other users by clicking on forgotten password, it removes the waiting for a second email with a password, and it means you just need to click on a link rather than clicking on a link and then entering the system generated password.
Definitely interesting to see what everyone is doing though!
It's amazing what's in Google.