Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Devise with rails 4 authenticated root route not working

What I'm trying to do

I want to send a user to the registrations#new page if they aren't logged in.

After you enter login info and click submit, I want you to be sent to the registrations#show page.

What is happening

It sends you to the registrations#new page when you're not logged in (correct so far). But when you submit the login form, it sends errors out with a redirect loop. The server's output is just this block repeated over and over:

Started GET "/" for 127.0.0.1 at 2013-09-25 02:31:59 -0400
Processing by RegistrationsController#new as HTML
  User Load (0.7ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 8 ORDER BY "users"."id" ASC LIMIT 1
Redirected to http://lvh.me:3000/
Filter chain halted as :require_no_authentication rendered or redirected
Completed 302 Found in 2ms (ActiveRecord: 0.7ms)

I can't seem to figure it out. It does log you in, as I can see that by manually navigating to a different page, but the authenticated root path is not working correctly. I've tried a few different combinations in my routes file and can't seem to get it. The code I'm using is based off of this thread

My code

In my application controller I have before_filter :authenticate_user!

My routes file:

devise_for :users, :controllers => {
  :registrations => "registrations"
}

devise_scope :user do
  root to: "registrations#new"
end

authenticated :user do
  root to: "registrations#show", :as => "profile"
end

unauthenticated do
  root to: "registrations#new", :as => "unauthenticated"
end
like image 625
Tom Prats Avatar asked Sep 25 '13 06:09

Tom Prats


People also ask

How to authenticate user through API in rails app?

Most of the time when we implement API endpoints on our Rails app, we want to limit access of these API to authorized users only, there’s a few strategy for authenticating user through API, ranging from a simple token authentication to a fullblown OAuth provider with JWT.

Does integrating devise Auth with rails 7 have any undocumented twists?

Integrating Devise Auth with Rails 7 has some undocumented twists. Learn about them here or use the included template to bypass them

Can I use devise in rails 7?

You’re now able to run your app and it should include pages like /users/sign_up and /users/sign_in. In theory Devise should work now but, unfortunately, the view links and redirects used by Devise won’t work in Rails 7. Let’s fix that.

How to install rails 7 Turbo Gemfile?

You can either add it your Gemfile manually, or pick up the latest version automatically by running the following in your console Now install it, via the console. Then— just like on the Devise readme — we generate the Devise config. Now, we need to do something a little special for Rails 7. Rails 7 includes Turbo as a cornerstone component.


3 Answers

First, you should customize Devise::RegistrationsController (you can add file app/controllers/registrations_controller.rb)

And see prepend_before_filter on devise registrations_controller.rb

prepend_before_filter :require_no_authentication, :only => [ :new, :create, :cancel ]
prepend_before_filter :authenticate_scope!, :only => [:edit, :update, :destroy]

Add show action to prepend_before_filter :authenticate_scope!

registrations_controller.rb

class RegistrationsController < Devise::RegistrationsController
  prepend_before_filter :require_no_authentication, :only => [ :new, :create, :cancel ]
  prepend_before_filter :authenticate_scope!, :only => [:edit, :update, :destroy, :show]

  # GET /resource/sign_up
  def new
    super
  end

  # POST /resource
  def create
    super
  end

  # GET /resource/edit
  def edit
    super
  end

  def update
    super
  end

  # DELETE /resource
  def destroy
    super
  end

  def show
  end


  protected

  def after_sign_up_path_for(resource)
    after_sign_in_path_for(resource)
  end

end

Also copy the view of devise registration (edit and new template) to /app/views/registrations/ and You can make a file show.html.erb in /app/views/registrations/ folder for a profile page.

For routes of devise looks like :

devise_for :users, :skip => [:registrations]

devise_for :users, :controllers => {
  :registrations => "registrations"
}

authenticated :user do
  devise_scope :user do
    root to: "registrations#show", :as => "profile"
  end
end

unauthenticated do
  devise_scope :user do
    root to: "registrations#new", :as => "unauthenticated"
  end
end

Last, you to set a "path" in after_sign_in_path_for(resource) and after_sign_out_path_for(resource_or_scope) at file application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery

  private

   def after_sign_in_path_for(resource)
     # After you enter login info and click submit, I want you to be sent to the registrations#show page
     profile_path
   end
   def after_sign_out_path_for(resource_or_scope)
     new_user_session_path
   end
end

Note: I have tried this (to make sample apps), and it works. See log when sign in here, and log sign out here

like image 181
rails_id Avatar answered Oct 23 '22 20:10

rails_id


The redirect to registration#new is default so all you need to do is this (in your route file):

devise_for :users, :controllers => {
  :registrations => "registrations"
}

devise_scope :user do
  root to: "registrations#show" # This is the root path of the user when you are logged in
end

unauthenticated do
  root to: "registrations#new", :as => "unauthenticated"
end

# I dont't think this part is neccesary... Try if it works without
authenticated :user do
  root to: "registrations#show", :as => "profile"
end
like image 21
jokklan Avatar answered Oct 23 '22 19:10

jokklan


Do not use routes to do the jobs belonging to controller.

To redirect an user to certain page after signing up, use Devise built-in after_sign_up_path_for and override it.

class ApplicationController
  def after_sign_up_path_for(resource)
    faked_user_profile_path(resource)
  end
end

For routes, I'm not very aware of all of them except devise_for part. But for the redirecting feature, this overriding should be enough.

like image 2
Billy Chan Avatar answered Oct 23 '22 19:10

Billy Chan