« Better yet, make password masking optional | Main | Boston CFUG meeting this Thursday, July 16th »

Three methods for password reveal

In my last post, I wrote about whether password fields should be masked or revealed so that users can see the passwords as they type them. One method I mentioned in that post is adding a checkbox to turn password masking on and off depending on the user's preferences.

Since then, I've come across another technique that is worth looking in addition to the first. Let's examine.

Technique 1: Users control password reveal with a checkbox
This option is able to give everyone (both your customers and Jakob Nielsen) what they want since customers can hide or show the password at their convenience. Better yet, you can always store the customer's preference in a cookie and show them the same behavior each time they enter their password.

Username:
Password:
Show password

To add this kind of control to your form, you add two new elements: first, a checkbox (that's kind of obvious); and second, a text input field with the exact same size, class and/or style as the password field, but a declaration of "display: none;" in the style:

...<tr>
<td>Password: </td>
<td><input type="password" name="userpass" id="userpass" size="25" value="oh nose you can see this" onkeyup="copyTo(this, 'userpasstext');" />
<input type="text" name="userpasstext" id="userpasstext" size="25" value="oh nose you can see this"  onkeyup="copyTo(this, 'userpass');" style="display: none;" /></td>
</tr>
<tr>
<td></td>
<td><input type="checkbox" name="reveal" onclick="revealPassword(this.checked);" /> Show password</td>
</tr>
</table>

Note that both the password field and the text field have an onkeyup event handler which calls a function named copyTo(). The copyTo(). function takes two arguments: a handler to the current form field, so that you can access the characters that have been typed into it, and the name of the other field, so that we can copy those characters to it to keep the contents of the two fields identical. Then the checkbox contains a call to revealPassword(), passing the checked status to handle whether the password is revealed or masked:

<script>
function revealPassword(reveal) {
    if(reveal) {
        document.getElementById('userpass').style.display = 'none';
        document.getElementById('userpasstext').style.display = 'inline';
    } else {
        document.getElementById('userpasstext').style.display = 'none';
        document.getElementById('userpass').style.display = 'inline';
    }
}

function copyTo(source, destination) {
    document.login[destination].value = source.value;
}
</script>


Technique 2: Automatically reveal the password during focus
I observed this while setting a password on the Sprint site. This option is fast and easy-- you save the user from having to check off the checkbox as in the first technique-- but it's not as flexible for users who want to see their password in cleartext all the time. Here's what it looks like:

Username:
Password:

The code in this technique is very similar to that of the first (and the JavaScript code remains the same), but instead of controlling the reveal in the event handler of a checkbox, you add an onfocus() handler to the password field, and an onblur() handler to the text field. Each calls the revealPassword() function, passing the appropriate value:

...<tr>
<td>Password: </td>
<td><input type="password" name="userpass" id="userpass" size="25" value="oh nose you can see this" onkeyup="copyTo(this, 'userpasstext');" onfocus="revealPassword(true);" />
<input type="text" name="userpasstext" id="userpasstext" size="25" value="oh nose you can see this"  onkeyup="copyTo(this, 'userpass');" onblur="revealPassword(false);" style="display: none;" /></td>
</tr>
<tr>
<td></td>
<td><input type="checkbox" name="reveal" onclick="revealPassword(this.checked);" /> Show password</td>
</tr>
</table>

I mentioned three techniques in the title, didn't I? The last is from the iPhone, though I have no idea how to accomplish it on the web.


Technique 3: Reveal the last character, mask the rest
I noticed this option in the iPhone's interface, and I think it's a nice way to provide strong security while still giving the user the ability to see that they've typed accurately. As you type, the last character you entered is displayed as cleartext, and the rest are obscured. After 2 or 3 seconds, even the last character converts to a bullet.

iphone-login.jpg

If you do figure out how to recreate this interface on the web, definitely let me know. It might be easy to save text to a hidden field as it's typed, but how would you handle changes in the middle of the string? [Note: In the comments below, Charlie Griefer points out a jQuery plugin that will do exactly this. Thanks, Charlie!]

Comments (4)

Charlie, that plugin fits the bill perfectly-- thanks for finding it. It even handles characters inserted in the middle of the string without any problems.

Tom, I've been considering this too and the iPhone (actually my Symbian smartphone does this too) method seems like a good compromise.

But while this may be ok on a small device where you could easily cover the screen in any situation, I'm not sure it's appropriate in cases where the form could be displayed on a larger screen (i.e. regular web pages).

They may not be typical but there are circumstances where other people will be looking at the screen as you type, not just snoopers but invited onlookers. Consider training situations or presentations. Imagine you're demonstrating your app to 1000 people at a conference and as you log in there's your super-admin password on the wall for everyone to see!

I think your Technique 1 should be the only option. It's an extra click, but then it's only there as an aid if the user is having trouble and wants to check their typing.

Post a comment