2012-05-10 20 views
10

De la misma manera que la mayoría de sitios web funcionan, debía almacenar "UsErNaMe" en la base de datos pero permitirles a los usuarios iniciar sesión con "username".Idear: Permitir a los usuarios registrarse como "UsErNaMe" pero iniciar sesión con "nombre de usuario"

Esta es una característica bastante obvia y necesaria, y muchas personas parecen haberlo preguntado, pero la solución que sigo tropezando parece desconectada de la propia documentación de Devise.

Por ejemplo, considere esta entrada del blog: http://anti-pattern.com/2011/5/16/case-insensitive-keys-with-devise

[...] de lo que has encuentra con el problema de que algunos usuarios les gusta escribir ciertas letras en sus nombres de usuario (correo electrónico y/o nombre de usuario) en mayúsculas, pero se espera que sea sensible a las mayúsculas cuando intentan iniciar sesión. a no petición razonable [...]

fresco! Eso es lo que quiero.

Su solución:

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

Esa es la solución que seguir encontrando. Pero aquí está la documentación para esa opción de configuración:

# 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 ] 

En particular: "Estas claves se downcased al crear/modificar un usuario." En otras palabras, el nombre de usuario está siendo descifrado en la base de datos.

Para verificar:

User.create username: "UsErNaMe", password: "secret", email: "[email protected]" 
#=> <User username="username"...> 

Me estoy perdiendo algo dolorosamente obvio?

Respuesta

10

De devise wiki: necesita sobrescribir el método de find_first_by_auth_conditions de su modelo.

ejemplo ActiveRecord:

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 

Puede eliminar OR lower(email) = :value parte si no es necesario autenticación por correo electrónico también.

De esta forma no es necesario que liste username en case_insensitive_keys y no se descargará en la base de datos.

+0

Esto, por supuesto, solo funcionará si declaró un atributo virtual de inicio de sesión en el modelo de usuario, configúrelo como su dispositivo: authentication_keys => [: login] y use ese atributo en su formulario de inicio de sesión. –

+6

también, aunque permite la entrada de mayúsculas y minúsculas en la base de datos, quiere asegurarse de que la singularidad no distinga entre mayúsculas y minúsculas; de lo contrario, permite tanto 'Nombre de usuario' como 'Nombre de usuario' pero el primer hallazgo en inferior los hará confluir. Por lo tanto, agregue validates_uniqueness_of: username,: case_sensitive => false –

+0

Works. Además, buena sugerencia, viktor. – danneu

Cuestiones relacionadas