Skip to content

How To: Redirect to a specific page when the user can not be authenticated

idoo edited this page Apr 17, 2013 · 19 revisions

If a user is not authenticatable you can redirect to a specific page.

For this example we want to use the entire URL with a particular sub-domain. Devise uses the path not the entire URL by default. The workaround is to use a custom failure app inherited from Devise failure app.

Rails 3

class CustomFailure < Devise::FailureApp
  def redirect_url
    if warden_options[:scope] == :user
      new_user_registration_path
    else
      new_user_registration_path
    end
  end
  def respond
    if http_auth?
      http_auth
    else
      redirect
    end
  end
end

And add the following in config/initializers/devise.rb:
config.warden do |manager|
  manager.failure_app = CustomFailure
end

If you’re getting an uninitialized constant CustomFailure error, and you’ve put the CustomFailure class under your /lib directory, make sure to autoload your lib files in your application.rb file, like below

config.autoload_paths += %W(#{config.root}/lib)

Rails 2.3.x

class CustomFailure < Devise::FailureApp
  include ActionController::UrlWriter
  def respond!
    options = @env['warden.options']
    scope   = options[:scope]

    redirect_path = if mapping = Devise.mappings[scope]
      eval("new_#{scope}_session_url(:host => 'secure.domain.com', :protocol => 'https')")
    else
      "/#{default_url}"
    end
    query_string = query_string_for(options)
    store_location!(scope)

    headers = {}
    headers["Location"] = redirect_path
    headers["Location"] << "?" << query_string unless query_string.empty?
    headers["Content-Type"] = 'text/plain'

    [302, headers, ["You are being redirected to #{redirect_path}"]]
  end
end

And add the following in config/initializers/devise.rb:

config.warden do |manager|
  manager.failure_app = CustomFailure
end

See further explanation at Stackoverflow

Clone this wiki locally