Durante las últimas 2 horas, he intentado depurar un problema extraño en el dispositivo que no me permite iniciar sesión.
Estas son las cosas a las que también me refiero:
password
=> 'vinodsobale'
password == 'vinodsobale'
=> true
resource.valid_password?(password)
=> false
resource.valid_password?('vinodsobale')
=> true
Adjuntando la captura de pantalla también:
Nota: He habilitado el depurador dentro del dispositivo, por lo que el código anterior es el código interno del dispositivo.
Para mí, parece un problema en Devise.secure_compare
.
password.encoding
y decirnos el resultado? Esto es lo único que se me ocurre que podría salir mal allí. También puede jugar::BCrypt::Engine.hash_secret(password, salt)
y comparar eso con el hash realmente almacenado. Porque esa comparacióntext.bytes
también puede resultar útil.password.bytes
y'vinodsobale'.bytes
solo para asegurarte?password
? Si es así,NULL character \0
debería estar codificado en Unicode ypassword == 'vinodsobale'
no debería regresartrue
.Respuestas:
Este problema se debe a un error conocido de corrupción de cadenas en Ruby 2.2.0 que se corrigió en 2.2.2.
Como se describe en el informe de error , la corrupción se produjo cuando BCrypt llamó a una API específica de creación de cadenas desde su extensión C, que Devise v3.3.0 activó al llamar
::BCrypt::Engine.hash_secret
desde elDevise::Models::DatabaseAuthenticatable#valid_password?
método. En v3.5.0 se publicó una solución alternativa específica de Devise para este error.La solución es:
< 2.2.0
, o actualizar a>= 2.2.2
;>= 3.5.0
.fuente
Qué tal si
resource.valid_password?(password.to_s)
Espero que te ayude.
fuente
password == 'vinodsobale'
coincidencias. Eso sí, sivinodsoble
es de tipostring
(que todos podemos ver), entoncespassword
también esstring
así y.to_s
no producirá nada diferente. En segundo lugar, el código que acaba de mencionar es parte del código interno del dispositivo, cómo desea implementarlo, como abrir el código del dispositivo y parchearlo.password == 'vinosobale'
. ¿Podrías probarpassword === 'vidodsobale'
partidos? ¿Podrías leer esta pregunta - stackoverflow.com/questions/7156955/… ?Devise
DatabaseAuthenticatable#valid_password?
está utilizando un método llamadoEncryptor::compare
toma 2 objetos, la contraseña almacenada actual y la nueva contraseña que desea comparar, creo que hay un efecto secundario para este método que modifica el segundo parámetro en el medio, por lo que modificará el objeto en su lugar de una vez, se modificará dos veces, lo que conduce a un resultado falso, por lo que puede funcionar si pasó un objeto duplicado de contraseña. puedes intentar usarvalid_password? password.dup
fuente
resource.valid_password?('vinodsobale')
cada vez que solía ejecutar esto, solía funcionar y?return true
Podría ser un problema con la codificación entre la fuente original y su consola. Si ejecuta
password.codepoints
, debería poder ver la codificación real. La ejecución.codepoints
en la cadena de 'contraseña' sin procesar debería regresar[112, 97, 115, 115, 119, 111, 114, 100]
.fuente