Devise + Legacy DB:“密码”列

时间:2014-01-31 20:17:27

标签: ruby-on-rails ruby devise ruby-on-rails-4 legacy-database

我正在尝试将旧的CakePHP网站慢慢迁移到Rails 4.由于需要大量的工作,网站需要逐渐移动,一次只迁移一个,并从Active Admin开始。我已经看到很多关于做这样事情的问题,但是我需要考虑一些棘手的额外事情:

  1. 我无法修改CakePHP代码
  2. 我无法打破CakePHP网站
  3. CakePHP站点将其散列密码存储在名为“password”的数据库列中,而Devise不喜欢这样。它希望“密码”成为明文密码,并且已经习惯于尝试覆盖该DB列。
  4. 将整个网站迁移到Rails之后,我当然可以开始关注如何应用程序迁移到Devise的任意数量的答案,但是现在我需要工作使用现有应用

    由于

2 个答案:

答案 0 :(得分:1)

我能够通过安装可忽略的gem,并在默认范围内选择密码列AS encrypted_pa​​ssword来解决此问题。它很难看,但它有效。

class User < ActiveRecord::Base
  ignore_columns :password

  default_scope :select => "#{User.quoted_table_name}.*, #{User.quoted_table_name}.password AS encrypted_password"

  devise :database_authenticatable

  def valid_password?(password)
    hash = ::Digest::MD5.hexdigest("[SALT REDACTED]#{password}").downcase
    return hash == self.encrypted_password
  end
end

答案 1 :(得分:0)

我发现了这个:http://www.slideshare.net/napcs/rails-and-legacy-databases-railsconf-2009并遵循他的建议来创建sql视图来包装旧表。

这是我以前运行的(我在Limesurvey上添加了一个应用程序):

CREATE VIEW `users` AS
SELECT `uid` as `id`,
       `users_name` as `username`,
       `email` as `email`,
       `password` as `encrypted_password`,
       `full_name` as `full_name`,
       `role_names` as `role_names`,
       `parent_id` as `parent_id`,
       `lang` as `lang`,
       `one_time_pw` as `one_time_pw`,
       `created` as `created_at`,
       `modified` as `updated_at`
FROM `lime_users`;"

问题是您必须在sql视图中包含基表中没有默认值的所有列,以便您插入到视图中。这是将“丑陋”列名称标准化为导轨友好列名称的好方法。

我的用户模型:

class User < ActiveRecord::Base
  before_save :save_encrypted_password
  self.primary_key = "id" # This needs to be declared, for some reason.

  def sha2(password)
    (Digest::SHA2.new << password).to_s
  end

  def valid_password?(password)
    return false if encrypted_password.blank?
    return Devise.secure_compare(sha2(password), self.encrypted_password)
  end
protected
  def save_encrypted_password
    if password == password_confirmation
      self.encrypted_password = sha2(password)
    else
      errors.add :password_confirmation, "has to match password"
    end
  end
end

反映数据库中的模型约束(非空,唯一值等)以避免任何更多陷阱也是一个好主意。 (经过近一个小时的晦涩难懂的错误消息后,我们学到了很多东西。)

希望这有帮助。