Several redirects after user update with devise - ruby-on-rails

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

Related

:require_no_authentication filter when reset user password

I have trouble with password resetting in my application.
On clicking "Reset password" button, I get an email "Reset password instructions" with link to "Reset password".
When signed in -
If I click on reset password link from the email, it is redirected to root path, not password reset page.
When logged out -
After logging out from my app, and then click on reset password link from the email, it redirects to edit password page.
Following this instructions - (https://github.com/plataformatec/devise/wiki/How-To:-Redirect-URL-after-sending-reset-password-instructions)
Passwords controller:
class Users::PasswordsController < Devise::PasswordsController
protected
def after_sending_reset_password_instructions_path_for(resource_name)
edit_user_registration_path
end
end
config/routes.rb:
devise_for :users, controllers: { passwords: 'passwords' }
But still getting the same error. Console log:
Started GET "/users/password/edit?reset_password_token=[FILTERED]" for 127.0.0.1 at 2019-04-09 13:59:26 +0300
Processing by Users::PasswordsController#edit as HTML
Parameters: {"reset_password_token"=>"[FILTERED]"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 10], ["LIMIT", 1]]
↳ /home/anatoly/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
Redirected to http://localhost:3000/
Filter chain halted as :require_no_authentication rendered or redirected
Completed 302 Found in 2ms (ActiveRecord: 0.3ms)
Can anyone help me?
Thank you in advance!
This behavior is correct.
The "Reset password" page is used only to recover the password, so if the user is already logged the page isn't shown. Logged users can use the route /users/edit to edit their password.
Here is how Devise's recover password controller prevent logged user from accessing the "Reset Password" page:
controllers/devise/passwords_controller.rb#L4
Calls require_no_authentication
devise_controller.rb#L114-L116
Detects the logged user and redirects to after_sign_in_path_for path

Rails app tries to GET "/users/logo.png" and shows ActiveRecord::RecordNotFound (Couldn't find User with 'id'=logo) with every submit

So at every submit request my rails server shows it is trying to get the logo and then shows there is no user with id = logo.png. Can somebody please help me!
Detailed error message:
Started GET "/users/2" for 127.0.0.1 at 2016-10-02 19:01:18 +0530
Processing by UsersController#show as HTML
Parameters: {"id"=>"2"}
User Load (0.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
User Load (0.5ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
Rendered users/show.html.erb within layouts/application (1.8ms)
Rendered layouts/_header.html.erb (0.0ms)
Rendered layouts/_sidebar.html.erb (1.0ms)
Completed 200 OK in 130ms (Views: 126.9ms | ActiveRecord: 0.5ms)
Started GET "/users/logo.png" for 127.0.0.1 at 2016-10-02 19:01:18 +0530
Processing by UsersController#show as PNG
Parameters: {"id"=>"logo"}
User Load (1.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 0 LIMIT 1
Completed 404 Not Found in 3ms (ActiveRecord: 1.0ms)
ActiveRecord::RecordNotFound (Couldn't find User with 'id'=logo):
app/controllers/users_controller.rb:43:in `show'
Here is my routes file:
Rails.application.routes.draw do
root 'dashboard#show'
get 'signup' => 'users#new'
get 'admins' => 'users#admins_dashboard'
delete 'users' => 'users#destroy'
get '/users/edit/:id' => 'users#edit'
resources :users
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
end
My controller action for users:
def show
#user = User.find(params[:id])
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
redirect_to '/'
else
redirect_to '/signup'
end
end
the model for users:
class User < ActiveRecord::Base
has_secure_password
def admin?
self.role == 'admin'
end
end
This happened due to the way the browser resolves relative urls. When you use a fully qualified url for an image src(eg: http://example.com/logo.png), the browser doesn't have to do anything. It just issues a request to that URL. However, when you use relative URLs(without the protocol and domain), the browser has to figure out the full URL to issue the request.
You had <img alt="Brand" src="logo.png" /> in your layout, so the browser used the current context to resolve the full URL for that image. When you were on http://example.com/users/1, the src was resolved to http://example.com/users/logo.png because it used the current path. When you were in the homepage the logo could be found because you were at the root path, so it resolved that src to http://example.com/logo.png.
One way to solve this is to prepend a slash to the src <img alt="Brand" src="/logo.png" /> forcing the browser to resolve it at the root of your domain. That will only work in your rails app if that image is on the public folder.
If you placed the image inside your assets, it's best to use rails image_tag helper. image_tag("logo.png").

Filter chain halted as :require_no_authentication rendered or redirected

I have used devise gem and generated views using devise commands with User as the name.
To show the login/logout link in the entire application, I am adding this to my layouts/application.html.erb
<% if user_session.present? %>
<%= link_to "logout", destroy_user_session_path, :method => 'delete' %>
<% else %>
<%= link_to "Login", new_user_session_path, :method => 'get' %>
<% end %>
<%= yield %>
And This is the home controller that have only index action:
class HomeController < ApplicationController
def index
end
end
The root is defined to point to home#index.
When I am launching the app, it is showing the Login link, upon clicking on the link, I am getting the following error:
Started GET "/users/sign_in" for ::1 at 2015-11-23 23:15:32 +0530
Processing by Devise::SessionsController#new as HTML
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
Redirected to http://localhost:3000/
Filter chain halted as :require_no_authentication rendered or redirected
Completed 302 Found in 10ms (ActiveRecord: 0.3ms)
Started GET "/" for ::1 at 2015-11-23 23:15:32 +0530
Processing by HomeController#index as HTML
Rendered home/index.html.erb within layouts/application (0.1ms)
User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
Completed 200 OK in 8ms (Views: 6.7ms | ActiveRecord: 0.4ms)
Please suggest where I am going wrong. I am not able to figure out the mistake.
For the HomeController you may need a skip_before_filter. At the top of the HomeController, :skip_before_filter :require_no_authentication, only: [:index]
I am not sure skipping the filter all together is the right solution. If that doesn't work for you, this post may be helpful.

Rails_Admin Sign out not Redirecting (Devise)

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

Rails devise without password

I am using devise and i am trying to allow user to modify their information without providing their information. I have followed the tutorial https://github.com/plataformatec/devise/wiki/How-To%3a-Allow-users-to-edit-their-account-without-providing-a-password.
I have this link to allow user to change their own settings
<%= link_to "Account Settings", edit_user_registration_path(current_user) %>
What I did his follow
rails g controller Registration
In the registrations controller replace the content with this
class RegistrationsController < Devise::RegistrationsController
def update
#user = User.find(current_user.id)
email_changed = #user.email != params[:user][:email]
password_changed = !params[:user][:password].empty?
successfully_updated = if email_changed or password_changed
#user.update_with_password(params[:user])
else
#user.update_without_password(params[:user])
end
if successfully_updated
set_flash_message :notice, :updated
# Sign in the user bypassing validation in case his password changed
sign_in #user, :bypass => true
redirect_to after_update_path_for(#user)
else
render "edit"
end
end
end
And in route.rb file i did this
devise_for :users, :controllers => { :registrations => "registrations" }
But it still bring me to the folder /views/devise/registration/edit.erb.html instead of bringing me to /views/registrations/edit.erb.html. I also restarted the server and my computer but no clue what else to do
Update: Note(customers = Users)
Started GET "/customers/edit.2" for 127.0.0.1 at 2012-12-09 20:06:03 -0500
Processing by Devise::RegistrationsController#edit as
[1m[35mCustomer Load (0.3ms)[0m SELECT `customers`.* FROM `customers` WHERE `customers`.`id` = 2 LIMIT 1
[1m[36mPage Load (0.2ms)[0m [1mSELECT `pages`.* FROM `pages` [0m
[1m[35mTag Load (0.2ms)[0m SELECT `tags`.* FROM `tags`
Rendered devise/registrations/edit.html.erb within layouts/application (0.1ms)
Rendered layouts/_shim.html.erb (0.0ms)
Rendered layouts/_iewrap.html.erb (0.0ms)
Rendered layouts/_header.html.erb (1.1ms)
Rendered layouts/_search_tags.html.erb (0.0ms)
Rendered layouts/_navigation.html.erb (0.8ms)
Rendered layouts/_thirdcol.html.erb (0.0ms)
Rendered pages/_link.html.erb (0.0ms)
Rendered layouts/_footer.html.erb (0.4ms)
Completed 200 OK in 41ms (Views: 36.4ms | ActiveRecord: 0.7ms)
Started GET "/assets/application.css?body=1" for 127.0.0.1 at 2012-12-09 20:06:04 -0500
Served asset /application.css - 304 Not Modified (5ms)
Started GET "/assets/activity_managers.css?body=1" for 127.0.0.1 at 2012-12-09 20:06:04 -0500
Served asset /activity_managers.css - 304 Not Modified (0ms)
this is the path i get to
http://localhost:3000/customers/edit.2
You got the name and location of your file wrong.
The file should be called edit.html.erb, not edit.erb.html.
The file should be localed in app/views/registrations.
Also, whenever a url has .id appended at the end, it means that you are passing something to the url helper that you shouldn't be. So in this case, you can remove the current_user argument and use your link like this:
<%= link_to "Account Settings", edit_user_registration_path %>
In config/initializers/devise.rb, uncomment this line config.scoped_views = true then restart Rails server. Also check if your edit.erb.html is in the right directory, it may be need to be in app/views/users/registrations/.
UPDATE:
You need to define edit method in your RegistrationsController because without it will inherit from Devise's RegistrationsController and consequently render Devises's views. Just add these two lines to the controller and it should work.
def edit
end

Resources