3
votes

Can anyone give any pointers to how we can customise Devise so that if an unauthenticated user visits the root_url, they are redirected to /users/sign_in but not shown the "You need to sign in or sign up before continuing." error message?

To expand further: we want that message to be shown if the user tries to visit a 'deeper' URL (/controller/restricted_action) directly without first authenticating, but for someone with the app bookmarked as www.app.com we just want to redirect them straight to the login page without any error being shown.

Had a look around through the SessionsController (to ascertain whether a custom controller could work) and various other places, but can't see a place or how we can override the behaviour in this way.

Any advice appreciated!

3

3 Answers

1
votes

This should remove the flash alert message if redirected from "/" to "/users/sign_in".

class ApplicationController < ActionController::Base
  before_action :keep_previous_url
  before_action :no_unauthenticated_alert_if_redirected_from_root

  def keep_previous_url
    session[:previous_url] = request.fullpath
  end

  def no_unauthenticated_alert_if_redirected_from_root
    if request.fullpath == "/users/sign_in" && session[:previous_url] == "/"
      flash.now.alert = nil
    end
  end
end
0
votes

@Anthony's suggestion above is good. Although I think we can improve on it slightly. With this below solution, there is only 1 before_action being called in the ApplicationController (the less the better since it's used by all), and then one in your root or home controller itself. Also, it won't keep storing the previous_url unnecessarily in the user session, saving memory.

Add this to your ApplicationController:

class ApplicationController < ActionController::Base
  before_action :_no_unauthenticated_alert_if_redirected_from_root

  private

  def _no_unauthenticated_alert_if_redirected_from_root
    return if session[:requiring_sign_in_from_root] != true

    session[:requiring_sign_in_from_root] = nil
    flash.clear
  end
end

and add this to the controller that serves your root "/" url:

class HomeController < ApplicationController
  prepend_before_action :_check_if_requiring_sign_in_from_root

  private

  def _check_if_requiring_sign_in_from_root
    session[:requiring_sign_in_from_root] = true unless user_signed_in?
  end
end

The methods don't need to be private, but I think it's good practice.

0
votes

I have fixed this by doing the following:

authenticated :user do
  root to: 'home#index', as: :home
end
root to: redirect('/users/sign_in')

Now I don't the error message when going to the root route.

Source: https://github.com/heartcombo/devise/wiki/How-To:-Require-authentication-for-all-pages