Skip to content

Email case sensitivity

croaky edited this page Sep 13, 2010 · 10 revisions

When a User signs up using Clearance, their email will be stored in the case they enter. By default, the email column is a simple string type. It does not use the :binary option provided by Rails.

This means that all MySQL SELECTs are case-insenstive. So, when a User signs in, if they type a different case than is actually stored, it will still find the User.

We made this design decision in Clearance so that:

  • the end user experience works as expected
  • the code is as light as possible
  • if you care about meeting the RFC 5321 specification for email, you can override Clearance’s defaults
  • the database index on email and password is intact

Know your database

We (thoughtbot) almost exclusively work with MySQL databases. If you are using a different database, please be aware of how Clearance is handling email case sensitivity.

Overriding: all downcase, all the time?

If you prefer tighter control, forcing all writes to the email attribute to be downcased, you can add a downcase_email callback in your User model:

before_save :downcase_email

protected

def downcase_email
  self.email = email.to_s.downcase
end

Nothing in Clearance will stop you from doing this.

Overriding: meet the RFC 5321 spec?

It is technically possible to have multiple email addresses in a mail server with the same characters in the local-part of different case. See the RFC 5321 specification.

In practice, that is rare. However, if you want to strictly meet the spec, we recommend that you:

  • change the email field to use the :binary option
  • add some site copy on your sign up & sign in pages to let the user know their email will be case-sensitive

Database index

For a few early versions of Clearance, we used the LOWER() SQL function on email for the authenticate method. That was to handle old records that may have uppercase characters. However, this caused the database not to use the database index. In an app with even just a few thousand users, that can make the authenticate method noticeably slower.

If you decide to use the downcase_email callback in your app, we recommend that you run a migration that downcases the value of the email column for all the records in the users table.