Rails_Admin Sign out not Redirecting (Devise) - ruby-on-rails

We are using Devise, Rails_Admin and Simple_Token_Authentication (for API) in our application.
Everything is working fine except for sign out. When we click on Sign out, following request is made and the user gets signed out.
Started DELETE "/admins/sign_out" for 127.0.0.1 at 2015-07-12 18:50:44
+0530 Processing by Devise::SessionsController#destroy as HTML Parameters:
{"authenticity_token"=>"rtSRPzpRN7cWEk8wV8q6VDAUB575ZV46JeFFlMFVOQc="}
Admin Load (0.4ms) SELECT "admins".* FROM "admins" WHERE
"admins"."id" = 1 ORDER BY "admins"."id" ASC LIMIT 1 (0.1ms)
begin transaction (0.1ms) commit transaction Completed 204 No
Content in 700ms (ActiveRecord: 0.5ms)
The problem is that the page does not redirect after sign out.
On pressing the sign out button again, here is the request:
Started DELETE "/admins/sign_out" for 127.0.0.1 at 2015-07-12 19:01:59
+0530 Processing by Devise::SessionsController#destroy as HTML Parameters:
{"authenticity_token"=>"dHuxA5hRosyquhlsRmchK3vW9bQOCM/YXYXUNMxTufc="}
Filter chain halted as :verify_signed_out_user rendered or redirected
Completed 204 No Content in 1ms (ActiveRecord: 0.0ms)
Here is the application controller (app/controllers/application_controller.rb):
class ApplicationController < ActionController::Base
protect_from_forgery
skip_before_filter :verify_signed_out_user
respond_to :html, :json
protected
# Overwriting the sign_out redirect path method
def after_sign_out_path_for(resource_or_scope)
request.referrer
end
end
Here is the devise related code in app/config/initializers/rails_admin.rb
config.authenticate_with do
warden.authenticate! scope: :admin
end
config.current_user_method(&:current_admin)
Please suggest. Thanks in advance!

The problem is in your after_sign_out_path_for(resource_or_scope).
request.referrer redirects to the current page.
Change the after_sign_out_path_for(resource_or_scope) accordingly. If you want to redirect to root_path, then below would work.
def after_sign_out_path_for(resource_or_scope)
root_path
end

Related

Several redirects after user update with devise

I'm trying to create a rails 5 applications with devise that's supposed to act like a social network, so every user has a profile.
After updating the user instead of going back to the profile, the server redirects to localhost, then there is a message Filter chain halted as :require_no_authentication rendered or redirected and only then the user profile is loaded.
Also on the profile a message is shown "You are already signed in".
My goal is to erase those redirects.
I tried to change the redirect in a custom RegistrationController but then it said there are too many redirects so I could't just replace it.
I tried to have different roots for authenticated and unauthenticated users in routes.rb but it didn't change the behaviour
I tried to get behind the :require no authentication but I'm actually not quite sure I understood it correctly and also it didn't change anything.
The after_sign_in_path_for is set to the user profile
This is the server output:
Started PUT "/users" for 127.0.0.1 at 2019-06-04 12:13:37 +0200
Processing by Users::RegistrationsController#update as HTML
Parameters: {"email"=>"asdf#asdf.de", "password"=>"[FILTERED]", "password_confirmat
ion"=>"[FILTERED]", "current_password"=>"[FILTERED]"}, "commit"=>"Update"}
User Load (0.8ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
User Load (0.6ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT
1
(0.3ms) BEGIN
(0.4ms) COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 295ms (ActiveRecord: 2.1ms)
Started GET "/" for 127.0.0.1 at 2019-06-04 12:13:37 +0200
Processing by Users::SessionsController#new as HTML
User Load (0.7ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER
BY `users`.`id` ASC LIMIT 1
Redirected to http://localhost:3000/users/1
Filter chain halted as :require_no_authentication rendered or redirected
Completed 302 Found in 15ms (ActiveRecord: 0.7ms)
Started GET "/users/1" for 127.0.0.1 at 2019-06-04 12:13:37 +0200
Processing by UsersController#show as HTML
Parameters: {"id"=>"1"}
User Load (0.6ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER
BY `users`.`id` ASC LIMIT 1
User Load (0.5ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT
1
Rendering users/show.html.erb within layouts/application
Rendered users/show.html.erb within layouts/application (1.1ms)
Rendered shared/_navbar.html.erb (0.7ms)
Completed 200 OK in 162ms (Views: 145.3ms | ActiveRecord: 1.1ms)
Also why does the user get signed in again after updating? Is it correct behaviour?
I cannot seem to fathom where the redirect to localhost ist happening and intervene. Any help would be appreciated.
Edit 1
So, to clarify. I tried to use an authenticated_root but then I get the errormessage Couldn't find User without an ID.
devise_scope :user do
authenticated :user do
root to: 'users#show', as: :authenticated_root
end
root to: 'users/sessions#new'
end
Also I can't manage to change the redirecting from to root to the user profile. So the RegistrationController is unchanged. I would like to say in the update method or somewhere else "after updating go to user profile".
It seems like your root_path is /users/sign_in, and when the user updates his account, you redirect him to the root... but the user is already signed in so he can't access to the new_user_session_pah. The fallback default location configured in Devise is the user's profile, so he's redirected to this route.
Have you configured an authenticated root?
https://github.com/plataformatec/devise/wiki/How-To:-Define-a-different-root-route-for-logged-in-out-users
It should fix your problem (:
I managed to solve it by adding a method to RegistrationController as follows:
def after_update_path_for(resource)
user_path(current_user)
end
That is, after updating user, Rails goes to root_path, that is sessions#new. But user's already logged in, so rails router redirects you to users#show
Why don't you set root "home#index" (or sth like that)
Rails.application.routes.draw do
devise_for :users
authenticated :user do
root 'secret#index', as: :authenticated_root
end
root "home#index"
end
and then, in your application_controller.rb you can just require users to login before using your page
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_user!
end
If you want to redirect user to users#show after update, you can override the after_update_path_for
class User::RegistrationsController < Devise::RegistrationsController
protected
def after_update_path_for(resource)
user_path(resource)
end
end

redirecting to root rather than controller/edit for password reset

NOTE: I'm not using Devise.
I'm implementing a password reset action and I have the controller Password_Resets with the following edit action:
def edit
end
def update
puts "I'm in the update!!"
if params[:user][:password].empty?
#user.errors.add(:password, "can't be empty")
render 'edit'
elsif #user.update_attributes(user_params)
log_in #user
flash[:success] = "Password has been reset."
redirect_to recipes_url
else
render 'edit'
end
end
When I'm trying to run through it, I put in the appropriate URL and I get the following response:
Started GET "/password_resets/igArFj9sYLt1J6k6Y2BjSg/edit?email=maggie%40example.com" for ::1 at 2016-04-20 21:49:58 -0500
Processing by PasswordResetsController#edit as HTML
Parameters: {"email"=>"maggie#example.com", "id"=>"igArFj9sYLt1J6k6Y2BjSg"}
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT 1 [["email", "maggie#example.com"]]
Redirected to http://localhost:3000/
Filter chain halted as :valid_user rendered or redirected
Completed 302 Found in 2ms (ActiveRecord: 0.1ms)
Why is it redirecting to localhost rather than the view app/views/password_resets/edit?? I can't seem to figure out a good way to "debug" this or see what's going on.
NOTE: I made that view incredibly simple to make sure it wasn't redirecting.
This is the view app/views/password_resets/edit:
<h1>This is my edit view </h1>
EDIT::: SOLUTION
So I was just an idiot. Essentially I have a validated user command that checked if the user was authenticated and the user was not. Therefore I need some more error handling.
Thanks you!!
The error is in your validations:
Filter chain halted as :valid_user rendered or redirected
I'm assuming you are calling this at the top of your controller
You can see in your web server logs:
Filter chain halted as :valid_user rendered or redirected
It's mean you have before_filter or before_action in a controller.
This filter is just ruby method - def valid_user and obvious that it contains a condition with redirect.
You need to debug this method.
You can read more about controller filters here

"redirect_to" --on console i get message that page is redirected but on the browser the page doesn't get displayed

The create method is getting executed properly as shown on the console but redirect is failing to render on the browser.
controller
def create
#try to authenticate the user - if they authenticate successfully, an instance of the User model is returned
#user = User.authenticate(params[:email], params[:password])
#if an instance is returned and #user is not nil...
if #user
#let the user know they've been logged in with a flash message
flash.now[:notice] = "You've been logged in."
#THIS IS THE MOST IMPORTANT PART. Actually log the user in by storing their ID in the session hash with the [:user_id] key!
session[:user_id] = #user.id
#then redirect them to the homepage
redirect_to "/"
return
else
#whoops, either the user wasn't in the database or their password is incorrect, so let them know, then redirect them back to the log in page
flash.now[:alert] = "There was a problem logging you in."
redirect_to "/log-in"
return
end
end
console
Started POST "/log-in? create=%7B%22method%22:%22PUT%22,%22responseType%22:%22json%22%7D" for 127.0.0.1 at 2015-05-21 12:51:36 +0530
Processing by SessionsController#create as HTML
Parameters: {"email"=>"harsh#gmail.com", "password"=>"[FILTERED]", "create"=>"{\"method\":\"PUT\",\"responseType\":\"json\"}", "session {"email"=>"harsh#gmail.com", "password"=>"[FILTERED]"}}
User Load (22.0ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'harsh#gmail.com' ORDER BY "users"."id" ASC LIMIT 1
this is user entered passwordharsh
this is encript hash passwors$2a$10$kPfxXAMxcWHhJjcO9ubXv.Q2xbCMPA6K2epe/dGX5EDAIcbmnvJDi
Redirected to http://localhost:3000/
Completed 302 Found in 307ms (ActiveRecord: 23.0ms)
Started GET "/" for 127.0.0.1 at 2015-05-21 12:51:37 +0530
Processing by UsersController#index as HTML
Rendered users/index.html.erb within layouts/application (0.0ms)
Completed 200 OK in 349ms (Views:324.0ms | ActiveRecord: 0.0ms)
I searched for similar questions and tried all the answers but its still not getting rendered on browser.
Please help if you know the answer
Thanks
Remove return from the last lines. Rails looks for the redirection/rendering on the last line of the action being called. Let me know if that does the trick.
Hope this helps!

Devise: one user getting a 302 and 401 error, no idea why, correct credentials not much in the log

I've got a Rails app which generally works fine, but one (that I can find) user is causing a 302 error, and they can't log in. The log looks like this:
Started GET "/d/sign_in" for 127.0.0.1 at 2014-12-15 05:38:14 +0000
Processing by Devise::SessionsController#new as */*
Rendered devise/sessions/new.html.erb within layouts/application (0.5ms)
Rendered layouts/_navigation.html.erb (2.3ms)
Rendered layouts/_messages.html.erb (0.1ms)
Completed 200 OK in 10.1ms (Views: 7.2ms | ActiveRecord: 0.8ms)
Started GET "/d/sign_in" for 127.0.0.1 at 2014-12-15 05:38:14 +0000
Processing by Devise::SessionsController#new as */*
Rendered devise/sessions/new.html.erb within layouts/application (0.7ms)
Rendered layouts/_navigation.html.erb (2.2ms)
Rendered layouts/_messages.html.erb (0.2ms)
Completed 200 OK in 10.9ms (Views: 8.1ms | ActiveRecord: 0.7ms)
Started GET "/" for 58.111.229.203 at 2014-12-15 05:38:20 +0000
Processing by DocumentsController#index as HTML
Completed 401 Unauthorized in 0.5ms
Started POST "/d/sign_in" for 58.111.229.203 at 2014-12-15 05:38:28 +0000
Processing by Devise::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"cvyg6GWTtpd4M1klk0j6APbv4h36+a99yb9k646BRZA=", "user"=>{"email"=>"admin#blank.net", "password"=>"[FILTERED]"}, "commit"=>"Sign in"}
Redirected to http://appdomain.com/
Completed 302 Found in 310.2ms (ActiveRecord: 0.0ms)
Started GET "/d/sign_in" for 127.0.0.1 at 2014-12-15 05:38:29 +0000
Processing by Devise::SessionsController#new as */*
Rendered devise/sessions/new.html.erb within layouts/application (0.5ms)
Rendered layouts/_navigation.html.erb (2.7ms)
Rendered layouts/_messages.html.erb (0.1ms)
Completed 200 OK in 10.1ms (Views: 7.4ms | ActiveRecord: 0.8ms)
Now, the 127.0.0.1 things concern me since this is a production environment, but it might be just a service (Pingdom) ensuring the app is still up. Nevertheless, this user can't log in and I can't figure it out. No other users are affected that I know of, and the user has everything they need to be able to log in. No detailed errors are in the log (like missing resources or similar), it just hangs when they log in. Any help would be great.
Update
Here's DocumentsController (the relevant parts):
class DocumentsController < ApplicationController
include ApplicationHelper
include DocumentsHelper
include ServerHelper
load_and_authorize_resource
def index
#documents = current_user.documents.includes(:template).includes(:user)
.includes(:pdf_result).created.page(params[:page])
.per(10)
#categories = current_user.brand.templates.all.group_by(&:category)
#assets = AssetResources.new(current_user)
end
...
Changing this user to an administrator does not fix the problem. I guess ApplicationController is relevant too, and this is it:
class ApplicationController < ActionController::Base
before_filter :authenticate_user!, :check_mode
protect_from_forgery
rescue_from CanCan::AccessDenied do |exception|
redirect_to documents_url, alert: exception.message
end
helper_method :current_user, :authorised_user
hide_action :current_user
def mode
#mode = Mode.first
end
def check_mode
flash.now[:alert] = mode.messages unless mode.all_online
end
private
def user_activity
current_user.try :touch
end
def authorised_user
#authorised_user ||= User.find(session[:user_id]) if session[:user_id]
end
end
UPDATE The credentials are correct, when that email address and an incorrect password are entered I get a bad credentials message. The correct credentials just hangs.
Check
Whether this "admin#blank.net" user exists in database.
You are providing correct credentials.
Because when sign in fails, devise internally performs redirection and 302 is HTTP response status code for URL redirection.
In the database, ensure whether this user exists and you are providing the right credentials.
I know this is old. But just in case someone has the same problem, as I just did, here is what fixed it for me:
In
config/initializers/session_store.rb
change
Rails.application.config.session_store :cookie_store, key: 'my_secure_session', httponly: false, secure: true
to
Rails.application.config.session_store :cookie_store, key: 'my_session'
Why I had this problem in the first place: I copied a running Rails 4 server with SSL and booted it up in dev mode without SSL. Commenting out force_ssl in application_controller.rb allowed me to start the server without ssl but left me with the 302 and 401 error and a redirect back to the sign-in page (without notification).

Devise+CanCan strange behaviour when deleting

I have implemented authentication with devise and manage role permissions with CanCan. My application manages Recipes and when I destroy a Recipe, I get my session closed and redirects me to sign_in view...
If I don't check authentication and permissions (see recipes_controller above) it works fine.
It's very strange and I have no idea why this happens. Please help.
Thanks
LOG:
Started POST "/recipes/21" for 127.0.0.1 at Thu Dec 08 19:53:30 +0100 2011
Processing by RecipesController#destroy as HTML
Parameters: {"id"=>"21"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = 5 LIMIT 1
Completed 401 Unauthorized in 44ms
Started GET "/users/sign_in" for 127.0.0.1 at Thu Dec 08 19:53:30 +0100 2011
Processing by Devise::SessionsController#new as HTML
Rendered devise/shared/_links.erb (2.5ms)
Rendered devise/sessions/new.html.erb within layouts/application (14.2ms)
Completed 200 OK in 52ms (Views: 20.8ms | ActiveRecord: 0.0ms)
RECIPES_CONTROLLER:
class RecipesController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource
def destroy
#recipe = Recipe.find(params[:id])
#recipe.destroy
redirect_to recipes_url, :notice => "Successfully destroyed Recipe."
end
ABILITY:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user
if user.role? :super_admin
can :manage, :all
else if user.role? :super_read_admin
can :read, :all
else
# manage reciped he owns
can :manage, Recipe do |recipe|
recipe.owner == user
end
end
end
end
end
Answer, per asker (see comments below)
You must make sure you include <%= csrf_meta_tags %> in your layout.
============================
(Original reply)
From Completed 401 Unauthorized in 44ms it looks like your user is not allowed to destroy this recipe. Check that recipe.owner.id is 5...
Try this in the console:
user = User.find(5)
puts user.role
ability = Ability.new(user)
ability.can? :destroy, Recipe.find(21)
What is the output of the second and the last commands ?

Resources