[WIP] Allow login with username or email address
Additional feature mentioned in #685.
The problem is that tl_member.email is not unique. It does have the eval.unique flag, but we could not set a real unique database index, because emails were not unique in the past and there are non-unique records.
Related: https://github.com/contao/core/issues/3421#issuecomment-45525809 and https://github.com/contao/core/pull/7176
We could add another column emailHash that holds a hash of the email address, this column can have an unique index on the database.
Why would a hash solve the problem of having multiple accounts with the same email address?
For the future imo the email address is better suited as the primary login identifier than a username. This way it's easy to normalize logins from different sources that also verify the email address (e.g. facebook) without having the user to enter anything (plus the login name does not have to be remembered by the user).
We could possibly add another (nullable unique) email field, use that for the login and let the user decide which one to use in the templates. And then remove the original one in Contao 5. But that's an ugly solution...
Why would a hash solve the problem of having multiple accounts with the same email address?
You are right, it would not :) I misread the commend and thought that the index length of the unique index is the problem.
I've missed that the email is not unique. I'll refactor this.
Are you planning to complete this PR?
Is it somehow possible without breaking BC?
I doubt it… maybe we could add a configuration to the bundle, so to have it explicitly enabled.
Yes, that would work. I am already using unique e-mail addresses in my installations, so I could use the feature. And I probably would. 😄
So i'm gonna refactor this.
Yeah, I simply use https://github.com/terminal42/contao-mailusername 😉
Just for the record:
For the future imo the email address is better suited as the primary login identifier than a username. This way it's easy to normalize logins from different sources that also verify the email address (e.g. facebook) without having the user to enter anything (plus the login name does not have to be remembered by the user).
Even though I prefer email addresses over usernames due to UX concerns, this change may not be correct.
A username is a representation of one distinct user account, while an email address is one identity. Identities may be:
- an email account
- an OAuth-Provider
This implies two things:
- there is a trust relationship between the site and the identity provider (e.g., we trust that the email provider correctly authorizes the account owner)
- a user account may have multiple identities (e.g., multiple email addresses)
This PR allows using an email address or the username for login while preserving the username. This violates both aforementioned points:
- We may not trust the email provider to correctly authorize the user (this is important in case this PR automatically allows password reset by email (?)
- The 1:n (user-account/identity) problem
Further, it comes with additional major security implications because it allows using email addresses to log in that may be publically known.
Same arguments against the contao-mailusername extension (even though I use for every project ;-))
Towards a solution:
- We should support the 1:n account:identity concept by allowing multiple email addresses.
- We should make using the username optionally for the log-in (we still have the user ID).
- We should make the login options configurable.
As discussed in the Contao call, a possible solution would be to allow email logins only if an email address is unique. Once there is another account with the same email address, the user can only log in with their username. In Contao 6, we could then enforce unique email addresses.
A case to consider is if user A uses user B‘s email address as a username, because then user B would no longer be able to log in with their email address. Another case is if user B tries to register with an email that user A uses as their username.
See https://github.com/contao/contao/issues/6354