Within the design of my web application, I am trying to now choose the final steps of the members profiles for security. *I need to choose if I should use a system which you login with a username or email, and which is more secure?

With the current members table design, I have this setup:

  • The member ID is randomized out of 8 digits.
  • They have a nickname to display when they are welcomed. E.g. Welcome, $nickname.
  • Passwords are encrypted using bCrypt.

On top of the security which I have added into the design of the web application, which is more secure? A username and password or email and password?

Also, I do know the new standards are to the email and password, as I am seeing more of.

7 Answers 7


Give them a choice. For example, my e-mail address is fairly long whilst I usually pick short usernames; you can develop your login form to accept both.

Usernames aren't for securing accounts, passwords are. It isn't for no reason that the username is visible when entered in the browser, whilst the password is hidden. Also, users often re-use usernames, which, in contrast with password re-use, should not be a problem. And, of course, e-mail addresses were and are never meant not to be shared with anyone.

But the main problem: you don't store usernames or e-mail addresses hashed / encrypted, because you want to use them for other purposes than logging in. If someone steals the database with your hashed passwords, they will also have the usernames and e-mail-addresses. Gone is the “security benefit”!

So, forcing users to log in using only the e-mail address (and the password) or only the username (and the password) makes no sense.

Your defense should be enforcing strong passwords, and making sure you encrypt them with a strong password hashing function. Don't forget to set the cost high enough.

Additionally, to prevent an attacker that did not steal your database from renting a bot net and brute-forcing weak user passwords, restrict the number of login attempts per hour per IP address. Also, if you encounter a lot of login attempts for an acccount, block login attempts from any IP address from which no successful login for the account has been done in the past.

  • 1
    In addition to blocking an IP address you can inform the user by sending an email, when there is unusual login activity, like logging in from another country, or logging in at different locations at the same time, or logging in in Germany and five minutes later in Singapore. Facebook and Gmail do this.
    – SPRBRN
    Commented May 12, 2014 at 13:18
  • @user2428118: good points, especially the advice to use random salts in addition to hashing the passwords from your linked source. Commented May 12, 2014 at 13:54

Having a username provides more obscurity than email does which provides security as a bruteforcer would requires the username before being able to perform an attack.

An email is not as obscure as a username as email. Users might use their email in every other account registration, subscription to newsletter or even posted it somewhere to have someone contact you. If a hacker does a bit of research or knows you and somehow got hold of your email address through social engineering you, they will have higher chances of doing a bruteforce attack or guessing password.

A username implements more security in this way as now the hacker needs to know both your username and password to do the attack. It's easier to get one's email address with legit reason than getting one's username. If you have features like 'adding username to friend list', you could instead implementing add by member ID and it is not used for login.

An email address offers convenience to user as they will need to memorise one lesser thing as most of us who owns and uses email often do remember their email address. Security and convenient is always a trade off of each other.

Also note that to keep the username obscure, make sure you're not returning message like "Username does not exist" upon fail login. Return something like "fail login: Please check your username/password"

Most banks I know they don't uses email address for authentication, they would prefer username as it provides more obscurity. You could consider username as another form of 'password' in this case, just that it's a less secured password as it's not encrypted and can be view in plaintext by others by peeking over the screen.


There is little to be gained by having a secret username or something of the like. As long as you enforce a suitable password policy, brute force attacks will be ineffectual, regardless of whether the username is public or not. If an attacker intercepts the password in someway, through a keylogger or packet sniffing, he can also intercept the secret username.

This problem is better thought of in terms of usability. Do you want your users to remember an email address a nickname, a secret login name and a password? Keep it simple.


Old question, but since the question is about security and not convenience I feel that all of these answers are lacking one important aspect: enumeration attacks. I agree that passwords and/or another second factor is what is being used to authenticate the users as user2428118 mentioned earlier and not the username/email, so I am not going to discuss that at all. Also, in the event of a database breach, neither username nor email is any more or less secure since they are both stored in plain text.

However one security aspect that none of these questions address is username/email enumeration. In application security, our goal is minimizing or eliminating the knowledge that a hacker has that would help them break into the system. If they can determine the username or email used for an account, that account is less secure than an account that the hacker has no knowledge of.

If we use usernames for authentication then we need a way to tell a user that their desired username is taken already when they are signing up. This can be exploited by a hacker to determine if a given username exists already. That's a bad thing because if they know the username, they can then try to log in with the most commonly used passwords from previous database breaches. These common passwords are readily available online.

However, if we instead use email addresses for authentication, when adding a new account and the email exists already, just send a password recovery email to the user instead of a new sign-up email. However in the UI, simply tell the user to check their email address for further instructions, but give no indication whether that address is valid or not.


  • Hacker can guess based on your name by using [email protected] or other commonly used addresses (e.g. [email protected], [email protected], etc) or by filling out web form and using the address in the email reply to attempt authentication. However users are generally free to choose any email address they want, even personal addresses, and the users signing in may not necessarily be affiliated with or employed by the website they are logging into, so in this case they wouldn't have a @company.com email address logging into the company.com website.
  • Enumeration attacks can be prevented.


  • Sometimes displayed online (e.g. "This post was created by {{username}} on {{date}}") whereas emails should hopefully never be displayed in plain text.
  • Enumeration attacks cannot be prevented
  • More vulnerable to dictionary attacks as people often choose simple usernames (e.g. their first name).

Bonus: With that said, one other (more difficult) way a hacker can determine whether a username or email exists in the system is by attempting to log in and looking at the page response times. Best security guidelines show that we want our passwords to be hashed with a slow hash, however if a username or email does not exist in the database, we won't have to verify the password hash because there is no matching user. If our hash takes 100 ms to perform and the database query takes 5 ms, the response times for a request for a valid user will be, on average, 95 ms slower than an invalid user. The way I get around this is to always hash the provided password, even if the user doesn't exist in the database, or if the user does exist, then I just verify the hash in the database.


While many will disagree, I maintain that a username is more secure for login than an email address:

1) There is no reason not to hash the username in the database in the same way you should hash the password, so the database crack argument is moot

2) A person's email address is practically public knowledge. Furthermore, it is already likely in the hands of the bad guys... your spam folder should be proof of that. Two secrets are better than one.

3) People need to be encouraged to use a password manager so they do not pick weak passwords OR weak usernames. If it can be easily remembered, how secure can it be?

4) Sites that unfortunately require emails as logins are a very good reason to have site-specific "login only" emails that forward to your actual email. And again, a password manager can treat these like usernames, automating the chore of keeping it all straight. Plus, if they neglect to capture email as a separate field, you will know precisely who leaked your login-only email address to whom.

5) A username, properly secured, is potentially more reliable, as people can lose control of a specific email address.

  • "There is no reason not to hash the username in the database" - If you hash the username, you would then have to validate the username/password combination using every single user in your entire database. This might be acceptable for 4-5 users, but say if your hash takes 50 ms to compute and you have only 1000 users, you're in to waiting almost 1 minute just to validate your login.
    – Mike
    Commented Mar 2, 2018 at 20:55
  • I only wait a few milliseconds: SELECT COUNT(id) WHERE usernameHash = @usernameHash AND passwordHash = @passwordHash; Save and index the hashes, problem solved. :-)
    – user127
    Commented May 30, 2018 at 21:59
  • Oh, I was thinking of hashing the username with something with a unique random salt, like PHP's password_hash(). If you're not using a unique salt, then you could SELECT how you have it, yes. If not, you would have to calculate the hash for every single user in the table.
    – Mike
    Commented May 30, 2018 at 22:12
  • Where the salt is added is a different matter. I typically do all that in the middle tier, away from any PHP, JavaScript or whatever.
    – user127
    Commented May 30, 2018 at 22:26
  • What's the middle tier?
    – Mike
    Commented May 31, 2018 at 1:11

All these answer are great, except for the fact that in real life is a miracle if a user remember his password. By using a username, is essentially like having 2 passwords. We tried one time to to this change and it was a nightmare. Support tickets increased with people that could not remember their usernames. Username list and Email list can both be found online. From a website operations point of view, given that both are about the same, I prefer the one that decreases support tickets.

  • I think it's quite a stretch to claim that a username is a second password... usernames aren't usually treated secretly and may even be public. Commented Feb 7, 2021 at 19:09
  • @multithr3at3d I think lovepie means that it's a 2nd password in that it's randomly generated and it's something new and random to memorize as opposed to a name/email.
    – schroeder
    Commented Feb 7, 2021 at 23:46

If you have use proper HTTPS and other security mechanisms, in security wise there will not be much different. But if user names are too complex, users may try to write them on sticky notes and put on desktop (probably with passwords). So go with less complex one.

If you can use two factor authentication, that would greatly enhance the security.

  • HTTPS has nothing to do with the complexity of credentials. I think the focus of the question relates to username/password guessing. It is entirely possible to guess credentials with the use of HTTPS (and other security mechanisms). Commented May 12, 2014 at 13:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .