开发者

Migrating from Authlogic to Devise

开发者 https://www.devze.com 2023-01-18 14:49 出处:网络
I\'ve previously implemented Authlogic for authorization on my site. Now however I wish to switch over to using Devise instead, and I\'m wondering if anyone has any experience with this. Perhaps anyon

I've previously implemented Authlogic for authorization on my site. Now however I wish to switch over to using Devise instead, and I'm wondering if anyone has any experience with this. Perhaps anyone's seen a blog post on 开发者_如何学编程the subject?

Thank you.


I myself switched from Authlogic to Devise recently and also didn't find any articles. However, in the simple case, once you've thrown away all of your user_session and other authlogic-related code, the main piece of work is converting your old users table to the format expected by devise.

My old table looked like this:

      Column       |           Type           |                     Modifiers                      
-------------------+--------------------------+----------------------------------------------------
 id                | integer                  | not null default nextval('users_id_seq'::regclass)
 login             | character varying(256)   | not null
 password          | character varying(64)    | not null
 created_at        | timestamp with time zone | not null
 updated_at        | timestamp with time zone | not null
 persistence_token | character varying(255)   | not null
Indexes:
    "users_pkey" PRIMARY KEY, btree (id)
    "index_users_on_persistence_token" UNIQUE, btree (persistence_token)
    "users_login_key" UNIQUE, btree (login)

and I determined that the table would have to contain at least the following info for devise (with many optional features enabled):

 id                   | integer                     | not null default nextval('contributors_id_seq'::regclass)
 email                | character varying(255)      | not null default ''::character varying
 encrypted_password   | character varying(128)      | not null default ''::character varying
 password_salt        | character varying(255)      | not null default ''::character varying
 confirmation_token   | character varying(255)      | 
 confirmed_at         | timestamp without time zone | 
 confirmation_sent_at | timestamp without time zone | 
 reset_password_token | character varying(255)      | 
 remember_token       | character varying(255)      | 
 remember_created_at  | timestamp without time zone | 
 sign_in_count        | integer                     | default 0
 current_sign_in_at   | timestamp without time zone | 
 last_sign_in_at      | timestamp without time zone | 
 current_sign_in_ip   | character varying(255)      | 
 last_sign_in_ip      | character varying(255)      | 
 failed_attempts      | integer                     | default 0
 unlock_token         | character varying(255)      | 
 locked_at            | timestamp without time zone | 
 created_at           | timestamp without time zone | 
 updated_at           | timestamp without time zone | 

So I defined an unadorned activerecord class in the migration class

 class ConversionUser < ActiveRecord::Base
   set_table_name "users"
 end

and then here's the "up" migration code I ended up using (with PostgreSQL):

add_column :users, :email, :string, :limit => 255
execute "UPDATE users SET email = login || '@somedomain.net'"
execute "ALTER TABLE users ALTER email SET NOT NULL"

add_column :users, :encrypted_password, :string, :limit => 128
add_column :users, :password_salt, :string, :limit => 255

require 'devise/encryptors/bcrypt'
ConversionUser.find(:all).each do |u|
  password_salt = Devise::Encryptors::Bcrypt.salt(Devise.stretches)
  u.update_attributes!(:password_salt => password_salt,
                       :encrypted_password => Devise::Encryptors::Bcrypt.digest(u.password, Devise.stretches, password_salt, Devise.pepper))
end

add_column :users, :confirmation_token, :string, :limit => 255
add_column :users, :confirmed_at, :timestamp
add_column :users, :confirmation_sent_at, :timestamp
execute "UPDATE users SET confirmed_at = created_at, confirmation_sent_at = created_at"
add_column :users, :reset_password_token, :string, :limit => 255

add_column :users, :remember_token, :string, :limit => 255
add_column :users, :remember_created_at, :timestamp
add_column :users, :sign_in_count, :integer, :default => 0
add_column :users, :current_sign_in_at, :timestamp
add_column :users, :last_sign_in_at, :timestamp
add_column :users, :current_sign_in_ip, :string, :limit => 255
add_column :users, :last_sign_in_ip, :string, :limit => 255

add_column :users, :failed_attempts, :integer, :default => 0
add_column :users, :unlock_token, :string, :limit => 255
add_column :users, :locked_at, :timestamp

remove_column :users, :password
remove_column :users, :persistence_token

add_index :users, :email,                :unique => true
add_index :users, :confirmation_token,   :unique => true
add_index :users, :reset_password_token, :unique => true
add_index :users, :unlock_token,         :unique => true

Note that here I've converted a plain password column into a bcrypt-encrypted column for Devise -- if you've used encrypted passwords with Authlogic, then you'll probably want to just rename the column (if necessary) and choose the correct encryptor module in config/initializers/devise.rb.

For reference, the "devise" clause in my User model looks like this:

devise :database_authenticatable, :registerable, :recoverable,
  :rememberable, :trackable, :validatable, :confirmable, :lockable,
  :timeoutable, :authentication_keys => [ :login ]

Note that overriding :authentication_keys like this so that users sign in with their login rather than their email address required me to modify some of the devise views: rails generate devise:views, then edit the files.

Hope this helps a bit. Good luck!


sanityinc's answer is great! Thanks very much!

But I had a different version of authlogic with encrypted passwords and my final up migration was:

rename_column :users, :crypted_password, :encrypted_password

add_column :users, :confirmation_token, :string, :limit => 255
add_column :users, :confirmed_at, :timestamp
add_column :users, :confirmation_sent_at, :timestamp
execute "UPDATE users SET confirmed_at = created_at, confirmation_sent_at = created_at"
add_column :users, :reset_password_token, :string, :limit => 255

add_column :users, :remember_token, :string, :limit => 255
add_column :users, :remember_created_at, :timestamp
rename_column :users, :login_count, :sign_in_count
rename_column :users, :current_login_at, :current_sign_in_at
rename_column :users, :last_login_at, :last_sign_in_at
rename_column :users, :current_login_ip, :current_sign_in_ip
rename_column :users, :last_login_ip, :last_sign_in_ip

rename_column :users, :failed_login_count, :failed_attempts
add_column :users, :unlock_token, :string, :limit => 255
add_column :users, :locked_at, :timestamp

remove_column :users, :persistence_token
remove_column :users, :perishable_token
remove_column :users, :single_access_token

add_index :users, :email,                :unique => true
add_index :users, :confirmation_token,   :unique => true
add_index :users, :reset_password_token, :unique => true
add_index :users, :unlock_token,         :unique => true

.. and it worked great for MySQL.


If you meet a 'invalid hash' error when a user login, add :encryptable in User model. I have migrated from authlogic to devise. My database is MySQL.


If you're getting encryptor errors, try changing these in devise.rb config:

config.stretches = 20
config.encryptor = :authlogic_sha512
0

精彩评论

暂无评论...
验证码 换一张
取 消