Designing an application forces you to think about the little details you normally take for granted – like logging in, for instance, and what happens when the user forgets his password. Sites follow a number of password-resetting policies, most of which I hate. Some things I considered this morning:
1) Not bothering with a password-resetting option – you forget it, tough cookies. Clearly the way to go for sites dealing with sensitive information (and with customer service departments to do human-mediated resets), but I chucked this option pretty quickly as unfriendly to users.
2) Letting the user enter their e-mail, and then e-mailing them their password. Done by a lot of sites. Always makes me squeamish when I see it, though – user passwords really shouldn’t be sent out over e-mail. Besides, my current database stores a salted hashed password, with a different salt for each user – when the user logs in, it does the salted hash on the password they provided and then compares that to what’s in the database. I don’t have the plaintext password to send you, even if I wanted to.
3) Letting the user enter their e-mail, and then e-mailing them a new, random password for the account associated with that e-mail. Sounded good until I envisioned some jerk typing my e-mail address into into the ‘reset your password’ box every day, just to irritate me. I’d really rather avoid a system that lets malicious users inconvenience others, so I chucked this option.
4) Going the secret question / secret answer route – asking for a secret question / secret answer on sign up and then e-mailing the user a new, random password only if they both provide their e-mail and the secret question. Solves the random jerk problem mentioned above, and if I saved the secret answer as a salted hash I wouldn’t have to worry so much about storing some sensitive information possibly also used to verify a bank account in my database. But I threw this option out because it adds two additional fields to the sign-up form. Sign-up needs to be simple, damnit.
5) Generating a gigantic random key when a user forgets their password and enters their e-mail. The user is sent an e-mail with a URL containing that gigantic random key, and when they click on it they’re logged into the system and can change their password normally. The key could have an expiry time on it to keep it from being a backdoor into the system that someone could (not likely, but hey) stumble across. Not bad, but this means the generic ‘change password’ function can’t ask for the old password, since it’ll occasionally be used by people who’ve completely forgotten their old password. And that’s a problem, because I don’t want someone leaving themselves logged in and having their password changed on them by the next random user to come along. So I’ll pass.
6) Generating a gigantic random key and sending it in an e-mail as part of a URL, just like last time, except the URL with the random key takes the user to a page where they can only enter a new password – and gives the user no indication of what account’s password they’re changing. I think we have a winner – there’s no passwords sent in plain text, no secret questions to gunk up the sign-up process, and if someone was lucky enough to stumble across the URL with the random key they could change the password but wouldn’t know what account to use it with.
Anyone else have any password resetting schemes they particularly like? Time for me to get to coding…
{ 5 comments… read them below or add one }
Every time I got to my online Verizon account I have to go through the “I forgot my password” process. Why? They don’t allow the password to be one you’ve used before, and they have strange rules for passwords that I can never remember.
I now have several sites where I use “I forgot my password” process instead of actually trying to remember my password. This disturbs me, but my lazy nature demands that I take the easy way out.
Back when I was (re) building this part of the Vaults product, I took a route much like #6.
You type in your email, you get a big secret key (assuming, of course, that email matches an account). That mail mentions pretty much nothing besides that key and some simple instructions.
The difference is, key in hand, you get a form where you have to provide the username that owns this key (mild authentication: it might be obvious, but this wasn’t in the email that contained the key). Only then you get the no-previous-password password change form.
My general feelings about the forgotten password mechanisms align with what you put above, which explains why we reached nearly the same solution.
I’m actually doing the same thing right now; I’m taking approach #2 or #3. I guess it depends on how secure and sensitive the information you store is. In our case, it’s not that sensitive, and I really don’t think there’s much of an issue with someone entering an email just to annoy someone.
I’m a bit surprised that most web frameworks don’t provide this kind of functionality out of the box. You really shouldn’t need to build most of this stuff (users/logins/passwords, etc.).
You know, I think RoR does have some plugins, etc. to let you get this functionality without writing it all yourself. The Login Engine (http://api.rails-engines.org/login_engine/) looks promising, for example. But it is a plugin rather than a part of the basic framework.
I’m at the point where if I don’t build the stuff myself, I won’t understand it, and I’ll end up doing something stupid. Ended up backtracking a bit after trying to borrow some code from the RoR forum ‘Beast’, for example – it didn’t save me the time I thought it would, because I didn’t know what the hell was going on. On the other hand, I understand my own forum code just fine.
i forgot my password but i still remmber the secret answer and the email secure but i want my old password i don’t want to change it