加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – Rails将普通旧字符串保存为SQlite作为BLOB?我

发布时间:2020-12-17 03:20:24 所属栏目:百科 来源:网络整理
导读:我不知道为什么会发生这种情况,但Rails将字符串保存为SQLite作为BLOB.在我的应用程序中创建新用户之前,我在保存到数据库之前使用其纯字符串密码和MD5: class User ActiveRecord::Base before_create :encrypt_password def encrypt_password self.password
我不知道为什么会发生这种情况,但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哈希密码来验证用户时,它每次都会失败. 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)"

我一直在为这个应用程序工作一个月的大部分时间,直到昨晚我为User模型编写一些测试时才会看到这个问题.尝试对用户进行身份验证的测试每次都会失败,因此我开始在控制台中手动构建用户,并发现密码永远不会匹配,因此所有用户查找都会失败.

用于创建用户的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",["password","5f4dcc3b5aa765d61d8327deb882cf99"],["role_id",2],["twitter",["updated_at",["uuid","7ab57110-889c-012e-e207-482a140835c4"]]

其中,当我转换为常规SQL工作正常时,所以必须在某处发生其他事情.到底是怎么回事?!?!

> sqlite3 3.6.12
> rails 3.1.0.rc4
> sqlite3-ruby 1.3.3

UPDATE

它变得陌生和陌生……如果我在我的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打开一张票,但这真是太奇怪了,我不想永远笑出社区,甚至暗示这样的事情可能会发生!

解决方法

事实证明这是一个编码问题.在这里查看门票: 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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读