gpt4 book ai didi

ruby-on-rails - Rails 将普通旧字符串作为 BLOB 保存到 SQlite?我快要疯了!

转载 作者:IT王子 更新时间:2023-10-29 06:28:32 25 4
gpt4 key购买 nike

我不知道为什么会这样,但 Rails 正在将字符串作为 BLOB 保存到 SQLite。在我的应用程序中创建新用户之前,我在保存到数据库之前获取他们的纯字符串密码和 MD5:

class User < ActiveRecord::Base
before_create :encrypt_password

def encrypt_password
self.password = Digest::MD5.hexdigest(self.password)
end
end

但是,密码字段每次都作为一个怪异的 BLOB 进入 SQLite!我什至可以说的唯一方法是在将表导出到 SQL 时,我可以看到该字段的真实性质:

INSERT INTO "users" VALUES (24, 'john.doe@example.com', X'3639366432396530393430613439353737343866653366633965666432326133');

什么鬼??所以现在当我尝试通过查找他们的电子邮件和 MD5 哈希密码来验证用户时,它每次都会失败。 REAL 字符串显然与 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
  • rails 3.1.0.rc4
  • sqlite3-ruby 1.3.3

更新

它变得越来越陌生......如果我在我的 encrypt_password 方法中对一些随机字符串进行硬编码,那么它就会正确地进入数据库:

def encrypt_password
self.password = 'foo'
end

我什至可以将它硬编码为字符串“password”的实际 MD5 散列,并且它有效:

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 的某个地方开一张票,但这太奇怪了,我不想因为甚至暗示可能会发生这样的事情而永远被社区 mock !

最佳答案

原来这是一个编码问题。在此处查看票证:https://github.com/rails/rails/issues/1965

hexdigest 返回一个 ASCII 字符串,但当您返回查询同一字段时,查询将作为 UTF-8 字符串运行。我假设一旦我手动向字符串添加一些内容,它就会在幕后转换为 UTF-8,然后作为 UTF-8 正确保存到数据库中。这是修复:

def encrypt_password
self.password = Digest::MD5.hexdigest(self.password).encode('UTF-8')
end

关于ruby-on-rails - Rails 将普通旧字符串作为 BLOB 保存到 SQlite?我快要疯了!,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6575334/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com