-
Notifications
You must be signed in to change notification settings - Fork 5.5k
How To: redirect to a specific page on successful (oauth) sign in
See How To: Redirect back to current page after sign in, sign out, sign up, update
This is pretty straight forward, for an oauth sign in, request.env['omniauth.origin']
is automatically set. You can also fall back to whatever you'd like:
class ApplicationController < ActionController::Base
protected
def after_sign_in_path_for(resource)
request.env['omniauth.origin'] || stored_location_for(resource) || root_path
end
end
Note this will only work if you are using devise to redirect a user after sign in. For example if you are using the sign_in_and_redirect
helper:
sign_in_and_redirect @user
class ApplicationController < ActionController::Base
protect_from_forgery
protected
def after_sign_in_path_for(resource)
sign_in_url = new_user_session_url
if request.referer == sign_in_url
super
else
stored_location_for(resource) || request.referer || root_path
end
end
end
If you don't put stored_location_for before request.referer you'll get some weird behaviour and sometimes, you won't get to the stored location.
Add below snippet to new action of Devise::SessionsController if you want to customise redirect url
if params[:redirect_to].present?
store_location_for(resource, params[:redirect_to])
end
Or you can do this in a controller you inherit from Devise::SessionsController
- first, in controllers/users/sessions_controller.rb
:
module Users
class SessionsController < Devise::SessionsController
def new
self.resource = resource_class.new(sign_in_params)
store_location_for(resource, params[:redirect_to])
super
end
end
end
In config/routes.rb
, you would have also added:
devise_for :users, controllers: {sessions: 'users/sessions'}
Because the code for after_sign_in_path_for
above only checks if request.referer == sign_in_url
, these methods (which call after_sign_in_path_for
) will also have to be overridden (else you will encounter redirect loops):
Devise::PasswordsController#after_resetting_password_path_for
Devise::RegistrationsController#after_sign_up_path_for
Devise::RegistrationsController#after_update_path_for
This can be done like so:
# routes.rb
devise_for :users, controllers: { registrations: 'users/registrations', passwords: 'users/passwords' }
# users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
protected
def after_sign_up_path_for(resource)
signed_in_root_path(resource)
end
def after_update_path_for(resource)
signed_in_root_path(resource)
end
end
# users/passwords_controller.rb
class Users::PasswordsController < Devise::PasswordsController
protected
def after_resetting_password_path_for(resource)
signed_in_root_path(resource)
end
end