Using the Devise gem, how can I redirect to the previous page after login, but only if the previous page requires authentication (otherwise redirect to a specific page I define)?
Required scenarios:
/my-private-account
> Devise detects authentication required and redirects to login > Successfully login > redirect to /my-private-account
/
(doesn't require authentication) > visit /login
> Successfully login > redirect to specific page eg. /dashboard
/about
(doesn't require authentication) > visit /login
> Successfully login > redirect to /dashboard
This is almost covered by the Devise Wiki , but their answer redirects back for ALL pages. Eg. from /
(doesn't require authentication) > visit /login
> Successfully login > redirects back to /
My authentication is defined in routes:
# routes.rb
authenticate :user do
resources :events
end
# application_controller.rb
class ApplicationController < ActionController::Base
before_action :store_user_location!, if: :storable_location?
private
# Redirect back to current page after sign in
# ref: https://github.com/heartcombo/devise/wiki/How-To:-Redirect-back-to-current-page-after-sign-in,-sign-out,-sign-up,-update
def storable_location?
request.get? && is_navigational_format? && !devise_controller? && !request.xhr?
end
def store_user_location!
# :user is the scope we are authenticating
store_location_for(:user, request.fullpath)
end
def after_sign_in_path_for(resource)
stored_location_for(resource) || dashboard_path
end
end
Is there a way I can check whether a route requires authentication? Then I could override after_sign_in_path_for
eg.
def after_sign_in_path_for(resource)
if stored_location_for(resource).requires_authentication? # something like this...?
stored_location_for(resource)
else
events_path
end
end
Or am I tackling this in the wrong direction and is there a better way?
Lastly, is there anything else I need to be aware of to make this work for omniauth too?
I think what you actually need to override is the storable_location?
method so you don't store locations you don't want to go back.
For example, in the controller that handles the /
or /about
routes, you could override that storable_location?
method to always return false so those locations are not stored, then stored_location_for
won't be set.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.