Я понятия не имею, почему это происходит, но Rails сохраняет строку в SQLite как BLOB.Перед созданием нового пользователя в моем приложении я беру его простой строковый пароль и MD5 перед сохранением в базу данных:
class User < ActiveRecord::Base
before_create :encrypt_password
def encrypt_password
self.password = Digest::MD5.hexdigest(self.password)
end
end
Но поле пароля каждый раз переходит в SQLite в виде чертова BLOB!Единственный способ, который я мог бы сказать, - при экспорте таблицы в SQL я вижу истинную природу поля:
INSERT INTO "users" VALUES (24, 'john.doe@example.com', X'3639366432396530393430613439353737343866653366633965666432326133');
Что за черт ??Поэтому теперь, когда я пытаюсь аутентифицировать пользователя, просматривая его электронную почту и хешированный пароль MD5, каждый раз происходит сбой.Реальные строки не соответствуют BLOB-объектам:
User.find_by_email_and_password('john.doe@example.com', Digest::MD5.hexdigest('password') => nil
Я никогда в своей жизни не использовал BLOB-объект, не говоря уже о поле пароля для пользовательской таблицы.Мои миграции четко определяют :string
как тип данных.Выполнение User.columns
ясно показывает:
#<ActiveRecord::ConnectionAdapters::SQLiteColumn:0x00000105256ce0 @name="password", @sql_type="varchar(255)"
Я работал над этим приложением большую часть месяца и никогда не видел эту проблему до прошлой ночи, когда я писал некоторые тесты для пользователя.модель.Каждый раз при попытке аутентификации пользователя произойдет сбой, поэтому я начал вручную собирать пользователей в консоли и пришел к выводу, что пароль никогда не будет совпадать, поэтому поиск всех пользователей завершится неудачей.
Информация отладки Rails для созданияпользователь выглядит так:
INSERT INTO "users" ("created_at", "email", "first_name", "last_login_at", "last_name", "login_count", "password", "role_id", "twitter", "updated_at", "uuid") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [["created_at", Mon, 04 Jul 2011 18:50:58 UTC +00:00], ["email", "braulio_towne@runolfsson.name"], ["first_name", "Ebba"], ["last_login_at", nil], ["last_name", "Bayer"], ["login_count", nil], ["password", "5f4dcc3b5aa765d61d8327deb882cf99"], ["role_id", 2], ["twitter", nil], ["updated_at", Mon, 04 Jul 2011 18:50:58 UTC +00:00], ["uuid", "7ab57110-889c-012e-e207-482a140835c4"]]
Что, когда я конвертирую в обычный SQL, работает нормально, так что где-то еще что-то происходит.Что происходит?!?!
- sqlite3 3.6.12
- рельсы 3.1.0.rc4
- sqlite3-ruby 1.3.3
ОБНОВЛЕНИЕ
Становится незнакомым и незнакомым ... если я жестко закодирую некоторую случайную строку в моем методе encrypt_password
, то он корректно попадает в базу данных:
def encrypt_password
self.password = 'foo'
end
Я могудаже жестко закодировать его в фактический хэш MD5 строки 'password', и он работает:
def encrypt_password
self.password = '5f4dcc3b5aa765d61d8327deb882cf99'
end
Но если я скажу это Digest::MD5.hexdigest('password')
, тогда он будет введен как BLOB.
Теперь, если я добавлю что-нибудь в строку, созданную дайджестом, то это сработает!
def encrypt_password
self.password = Digest::MD5.hexdigest(self.password) + ' '
end
Что это за черт ??Итак, сейчас моя тренировка состоит в том, чтобы добавить новую строку, а затем сжать ее:
def encrypt_password
self.password = (Digest::MD5.hexdigest(self.password) + "\n").chomp
end
Я чувствую, что должен где-то открыть билет в Rails, но это настолько удивительно, что я не хочурассмеяться над сообществом навсегда, даже предположив, что что-то подобное может произойти!