Question

In the same way most websites work, I was to store "UsErNaMe" in the database but let users login with "username".

This is a fairly obvious and necessary feature, and plenty of people seem to have asked it, but the solution I keep stumbling upon seems disconnected from Devise's own documentation.

For instance, consider this blog post: http://anti-pattern.com/2011/5/16/case-insensitive-keys-with-devise

[...]you’ve probably run into the problem that some users like to type certain letters in their logins (email and/or username) in uppercase, but expect it to be case-insensitive when they try to sign in. A not unreasonable request[...]

Cool! That's what I want.

His solution:

# config/initializers/devise.rb
Devise.setup do |config|
  config.case_insensitive_keys = [:email, :username]
end

That's the solution I keep finding. But here's the documentation for that config option:

# Configure which authentication keys should be case-insensitive.
# These keys will be downcased upon creating or modifying a user and when used
# to authenticate or find a user. Default is :email.
config.case_insensitive_keys = [ :username, :email ]

In particular: "These keys will be downcased upon creating/modifying a user." In other words, the username is being downcased in the database.

To verify:

User.create username: "UsErNaMe", password: "secret", email: "email@com.com"
#=> <User username="username"...>

Am I missing something painfully obvious?

Was it helpful?

Solution

From devise wiki: you need to overwrite devise's find_first_by_auth_conditions method in your model.

ActiveRecord example:

def self.find_first_by_auth_conditions(warden_conditions)
  conditions = warden_conditions.dup
  if login = conditions.delete(:login)
    where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
  else
    where(conditions).first
  end
end

You can remove OR lower(email) = :value part if you don't need auth by email too.

That way you don't need to list username in case_insensitive_keys and it wouldn't be downcased in the database.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top