Skip to content

How To: Change the default sign_in and sign_out routes

AndreyChernyh edited this page Nov 10, 2010 · 8 revisions

When you are using only one role with Devise you may want to change the sign in and sign out routes to /login and /logout (instead of /users/sign_in and /users/sign_out).

This does not work by default because Devise inspects the URL to find which scope you are accessing. So when it sees “/users/login”, it knows the scope is “user”, however, when you access “/login”, Devise cannot know which scope it should use. Luckily, Devise provides a mechanism to specify a default scope, allowing us to have short URLs.

Steps for Devise 1.1.0 with Rails 3.0.0

All you need to do is to specify in your routes the devise_scope being accessed in that URL:

devise_scope :user do
  get "/login" => "devise/sessions#new"
end

Since devise_scope is aliased to as, this is equivalent:

as :user do
  get "/login" => "devise/sessions#new"
end

Finally, you can also pass a block to devise_for:

devise_for :users do
  get "/login" => "devise/sessions#new"
end

Similarly for sign_out:

devise_scope :user do
  get "/logout" => "devise/sessions#destroy"
end

Note that when you’re overriding the Devise::SessionsController controller, in some cases it’s necessary to skip the default session routes and to redefine all this routes manually as follows:

devise_for :users, :controllers => {:sessions => 'custom_devise/sessions'}, :skip => [:sessions] do
  get 'signin' => 'custom_devise/sessions#new', :as => :new_user_session
  post 'signin' => 'custom_devise/sessions#create', :as => :user_session
  get 'signout' => 'custom_devise/sessions#destroy', :as => :destroy_user_session
end

This way :authenticate_user! and other helpers will be redirecting the user to the proper custom pages you defined.

Steps for Devise 1.0.6 with Rails 2.3.5

  1. in config/initializers/devise.rb change use_default_scope and default_scope (lines 81 and 85)
    config.use_default_scope = true
    config.default_scope = :user
  1. in config/routes.rb change devise_for route and add custom routes
    map.devise_for :users, :path_names => { :sign_in => 'login', :sign_out => 'logout' }
    map.new_user_session 'login', :controller => 'sessions', :action => 'new', :conditions => { :method => :get }
    map.user_session 'login', :controller => 'sessions', :action => 'create', :conditions => { :method => :post }
    map.destroy_user_session 'logout', :controller => 'sessions', :action => 'destroy', :conditions => { :method => :get }

Now this gives you already the ability to sign in and sign out through /login and /logout.
If you use before_filter :authenticate_user! somewhere in your controllers you will see that devise still redirects to /users/login. That is because the path to redirect to is hardcoded in Devise 1.0 due to limitations of Rails 2.3.

To get around this we can take a look at the solution here: How To: Redirect to a specific page when the user can not be authenticated

Clone this wiki locally