Skip to content

Instantly share code, notes, and snippets.

@JayTeeSF
Forked from rpheath/authlogic-to-devise.md
Created January 3, 2018 16:27
Show Gist options
  • Save JayTeeSF/f85a2974039e71442401e126a2e1b308 to your computer and use it in GitHub Desktop.
Save JayTeeSF/f85a2974039e71442401e126a2e1b308 to your computer and use it in GitHub Desktop.
Steps and troubleshooting tips when moving Authlogic to Devise.

How To: Authlogic to Devise

Step 1: Migration

  1. bin/rails g migration AuthlogicToDevise
  2. (see the file below for the actual migration, authlogic_to_devise.rb)
  3. bin/rake db:migrate

Step 2: Update Gemfile

  1. gem "devise", "~> 2.2.0"
  2. bundle install

Step 3: Install Devise

  1. bin/rails g devise:install
  2. (follow on-screen instructions, if any)
  3. To install Devise views for overriding: bin/rails g devise:views

Step 4: Update Code

  1. Replace any login_required filters with authenticate_user!
  2. If you define your own current_user methods, remove them so we are using the helpers provided by Devise (old helpers are often in lib/authenticated_system.rb)

Step 5: Setup Devise Model

  1. bin/rails g devise User (note that your model might be different than User)
  2. IMPORTANT: remove the created migration, we manually migrated the DB above
  3. Modify any of the inserted devise commands in your model, as desired

Tips / Troubleshooting

Keeping Existing UserSessionsController

To avoid having to create new views and use the Devise controllers, you can re-use the existing UserSessionsController pretty easily. I found that the devise_for :users wasn't enough, the route wasn't loading properly; so, tell devise_for which controller to use:

devise_for :users, :controllers => { :sessions => "user_sessions" }

Then just update your form to use @user instead of @user_session. Additionally, you need to modify UserSessionsController slightly:

  1. Delete all of the actions (new, create, destroy)
  2. Inherit from Devise::SessionsController (this will provide the devise actions)
  3. May need to add an entry into config/locales/devise.en.yml (for en.devise.user_sessions.user.[signed_in|signed_out])

Ensure Existing User Passwords Still Work

Rather than have everyone create new passwords, Devise can support Authlogic's encryption scheme. There are a few steps needed to make this work:

  1. Relies on the encryptable gem, so add this to your Gemfile: gem "devise-encryptable"
  2. bundle install
  3. Tell Devise to use the Authlogic schem by opening config/initializers/devise.rb and setting config.encryptor = :authlogic_sha512
  4. You also have to increase the stretches from 10 to at least 20 to match Authlogic's scheme, otherwise this won't work. So in the same file as the step above, find the config.stretches line and change it from 10 to 20 (keep it as 1 for test environment for performance purposes).
  5. Finally, in your User model, you have to tell Devise to use this extension via: devise :encryptable, ...
  6. Restart your server and your existing accounts should still work.

FIX: "undefined method `urlsafe_base64' for SecureRandom"

If you come across this error, it's most likely because you're running Ruby 1.8.7 instead of 1.9 (that method doesn't exist in 1.8.7). But, the good thing is it's not required, we can use hex to replace it.

  1. Create a file in config/initializers (mine is called secure_random_overrides.rb)
  2. See the code below in the file called secure_random_overrides.rb

Sign In/Out Routing

It's possible that some of your login/logout routes and helpers will be screwed up. Just making note that those will likely need updated, specifically:

  • logout_path => destroy_user_session_path

In addition to this, I've also had to specify a :user scope so the routes match up:

devise_scope :user do
  get "/users/sign_out", :to => "user_sessions#destroy"
end

(Note: sometimes just get "/sign_out", ... is enough)

It's also possible that you may need to specify the logout HTTP method in the devise config (defaults to :delete). I changed this to :get:

  • config.sign_out_via = :get
class AuthlogicToDevise < ActiveRecord::Migration
def up
add_column :users, :confirmation_token, :string, :limit => 255
add_column :users, :confirmed_at, :timestamp
add_column :users, :confirmation_sent_at, :timestamp
add_column :users, :unconfirmed_email, :string
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, :reset_password_sent_at, :timestamp
add_column :users, :remember_token, :string, :limit => 255
add_column :users, :remember_created_at, :timestamp
add_column :users, :unlock_token, :string, :limit => 255
add_column :users, :locked_at, :timestamp
rename_column :users, :crypted_password, :encrypted_password
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
remove_column :users, :persistence_token
remove_column :users, :perishable_token
remove_column :users, :single_access_token
add_index :users, :confirmation_token, :unique => true
add_index :users, :reset_password_token, :unique => true
add_index :users, :unlock_token, :unique => true
end
def down
remove_column :users, :confirmation_token
remove_column :users, :confirmed_at
remove_column :users, :confirmation_sent_at
remove_column :users, :unconfirmed_email
remove_column :users, :reset_password_token
remove_column :users, :reset_password_sent_at
remove_column :users, :remember_token
remove_column :users, :remember_created_at
remove_column :users, :unlock_token
remove_column :users, :locked_at
rename_column :users, :encrypted_password, :crypted_password
rename_column :users, :sign_in_count, :login_count
rename_column :users, :current_sign_in_at, :current_login_at
rename_column :users, :last_sign_in_at, :last_login_at
rename_column :users, :current_sign_in_ip, :current_login_ip
rename_column :users, :last_sign_in_ip, :last_login_ip
rename_column :users, :failed_attempts, :failed_login_count
add_column :users, :persistence_token, :string
add_column :users, :perishable_token, :string
add_column :users, :single_access_token, :string
remove_index :users, :confirmation_token
remove_index :users, :reset_password_token
remove_index :users, :unlock_token
end
end
if RUBY_VERSION == "1.8.7"
module SecureRandom
# this method doesn't exist in 1.8.7 so
# we are faking it by using hex()
def self.urlsafe_base64(args)
self.hex(args)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment