djangoemail

Why Django lowercases only the domain part of email addresses in normalize_email?


I've noticed that somebody has managed to register twice in a website that is made with Django with one email, Foo@example.com and foo@example.com.

I checked the code and found out that there's a class method in BaseUserManager named normalize_email that, according to the documentation, ...

Normalizes the email address by lowercasing the domain part of it.

I understand that the email address may be something like JaneDoe@example.com and if the part preceding @ is transformed too it would omit the distinction between the first and last name. Yet the problem described above rises. Why doesn't it non-case-sensitively check uniqueness of the email addresses later? Does it have a reasonable explanation or is it a bug that has to be reported and fixed?


Solution

  • According to the specification in RFC 5322, the local part is case-sensitive, while the domain part is case-insensitive. That means that Foo@example.com and foo@example.com are in fact different addresses, while foo@Example.com and foo@example.com are the same.

    However, each email service is free to implement local addressing as they please. Many email services choose to treat the local part as case-insensitive. Some email services (such as Gmail) choose to interpret only the part before an optional + sign as your actual mail address. The suffix can then be used to sort your mail, so for example all mail to foo+stackoverflow@example.com is delivered to foo@example.com and can be sorted to a stackoverflow folder. These are technically all different addresses, but the email service interprets them as the same address.

    Django follows the RFC, so it only normalises addresses when they are guaranteed to point to the same address according to the specification.