When i try to restrict access to signup, it seems impossible. I tried
class RegistrationsController < Devise::RegistrationsController
skip_before_filter :require_no_authentication
end
in app/registrations_controller.rb and changed routes to
devise_for :accounts, :controllers => { :registrations => "registrations" }
This does not work. Any suggestions why and what i could do/where i should look would be appreciated.
EDIT:
Does not work means: when i try to access /accounts/sign_up while being signed out, it actually works, but i should be redirected to sign_in.
WORKAROUND:
class RegistrationsController < Devise::RegistrationsController
skip_before_filter :require_no_authentication
private
def authenticate_account!(opts={})
opts[:scope] = :account
warden.authenticate!(opts) # if !devise_controller? || opts.delete(:force)
end
end
This removes the hardcoded check that skips authentication for EVERY Devise-controller. The code comes from lib/devise/controllers/helpers.rb.
So you want to change after sign-out path.
If you haven't set your root to devise sign in then
class ApplicationController < ActionController::Base
private
# Overwriting the sign_out redirect path method
def after_sign_out_path_for(resource_or_scope)
new_user_session_path
end
end
Related
I'm aware that there are already a few Stack overflow q&a's regarding this, but they have not helped solve my issue.
I have a custom user registrations controller that inherits from devise registrations controller, i.e.:
class UsersController < Devise::RegistrationsController
I want to disable the authentication filter in the devise registrations controller. i.e disable this line:
class Devise::RegistrationsController < DeviseController
prepend_before_filter :require_no_authentication, only: [ :new, :create, :cancel ]
so that no authentication is required to edit a user.
Other stack overflow answers have suggested skipping the filter in the custom controller, i.e.
class UsersController < Devise::RegistrationsController
skip_before_filter :require_no_authentication
end
but this does not work for me. When I attempt to edit a user, a page is displayed saying:
you need to sign in or sign up before continuing.
I don't think my routing is an issue. My routes are:
devise_for :users, :skip => [:sessions, :registrations, :passwords]
devise_scope :user do
resources :user
end
Thanks and much appreciated
You were looking for something like this:
skip_before_filter :authenticate_user!, :only => [:edit]
The before filter you are disabling is not used to skip authorization. It is used to check if an existing valid session already exists. This is hinted at in the last few lines by the redirect and message. This is handy to disable if want users to be able to switch sessions without signing out or as a security measure to keep old sessions from being restored which was my use case.
# Helper for use in before_actions where no authentication is required.
#
# Example:
# before_action :require_no_authentication, only: :new
def require_no_authentication
assert_is_devise_resource!
return unless is_navigational_format?
no_input = devise_mapping.no_input_strategies
authenticated = if no_input.present?
args = no_input.dup.push scope: resource_name
warden.authenticate?(*args)
else
warden.authenticated?(resource_name)
end
if authenticated && resource = warden.user(resource_name)
flash[:alert] = I18n.t("devise.failure.already_authenticated")
redirect_to after_sign_in_path_for(resource)
end
end
applying the following:
class Users::RegistrationsController < Devise::RegistrationsController
skip_before_action :require_no_authentication
end
I've tried the code on Devise's github. In my application controller, i have:
after_filter :store_location
def store_location
# store last url - this is needed for post-login redirect to whatever the user last visited.
if (request.fullpath != "/users/sign_in" &&
request.fullpath != "/users/sign_up" &&
request.fullpath != "/users/password" )
session[:previous_url] = request.fullpath
puts 'stores location'
end
end
def after_update_path_for(resource)
session[:previous_url] || dashboard_path
puts 'after update'
end
When I check my server, the puts statement from the store_location method appears, but the puts statement from after_update_path_for does not. How do I get the after_update_redirect to work?
Here is what devise says to do, but it isn't working:
https://github.com/plataformatec/devise/wiki/How-To:-Redirect-back-to-current-page-after-sign-in,-sign-out,-sign-up,-update
From the documentation:
(Object) after_update_path_for(resource) (protected)
The default url to be used after updating a resource. You need to overwrite this method in your own RegistrationsController.
So creating your ow RegistrationsController is correct. Here is a simpler solution though:
after_update_path_for calls signed_in_root_path(resource) which looks a home #{scope}_root_path. Scope here is often user (but if not you probably know what it is). In the case of 'user', implementing user_root_path in your application controller, returning your dashboard_url, should work.
def user_root_path
dashboard_url
end
Although it seemed a bit hackish to me at first, I believe it is quite 'ok'; the root path for the user-scope is could indeed be the dashboard page.
Here's how i solved the problem:
class RegistrationsController < Devise::RegistrationsController
protected
def after_update_path_for(resource)
puts 'this is happening yoyo mama'
flash[:notice] = "Account succesfully updated"
edit_user_registration_path
end
end
routes:
devise_for :users, :controllers => { :registrations => :registrations }
The only problem is that this will only do the redirect if changing the password is successful. If not, the redirect does not happen. Does anyone know how to make it so the redirect will also happen if there are errors?
As per the Devise docs, override the default and add the route. There's no need to set the flash message unless of course you want to change that as well.
# Example subclass/override (registrations_controller.rb)
class Users::RegistrationsController < Devise::RegistrationsController
protected
def after_update_path_for(resource)
user_path(resource)
end
end
# Example routing config (in routes.rb):
devise_for :users, :controllers => { :registrations => :registrations }
respond_with resource, :location => after_update_path_for(resource) is the code which set the redirection path after update. To change the default redirect, override following method in your application controller by adding the following code
def after_update_path_for(resource_or_scope)
dashboard_url
end
Overriding the route in the ApplicationController also did not work for me, but adding it to the Users::RegistrationsController worked.
For example,
class Users::RegistrationsController < Devise::RegistrationsController
def after_update_path_for(resource)
current_user
end
on a related note, the after_sign_in_path can be added to the SessionsController
class Users::SessionsController < Devise::SessionsController
def after_sign_in_path_for(resource)
current_user
end
my routes look like this:
devise_for :users, controllers: {
confirmations: "users/confirmations",
passwords: "users/passwords",
registrations: "users/registrations",
sessions: "users/sessions",
unlocks: "users/unlocks",
}
I tried to find solution by google and here in SO but couldn't found...
This is the only question. It has only one answer and it's accepted but doesn't work for me... Here is my code:
class RegistrationsController < Devise::RegistrationsController
before_filter :authenticate_user!
def new
puts "Method new was called"
super
end
end
When I'm not logged in at localhost:3000/sign_up page is displayed normally and Method new was called is printed. I want controller to redirect me into sign_in page if I'm not already signed in. Of course I can check it in new method and redirect but it's not a good solution... I'm sure there is a more elegant way. I even tried to use prepend_before_filter :authenticate_user! but it doesn't work too.
EDIT
I've defined routes for this controller in routs.rb
devise_for :users, :controllers => { :sessions => "sessions", :registrations => "registrations" }
Devise::RegistrationsController has require_no_authentication before filter by default.
So it's needed to skip it:
class RegistrationsController < Devise::RegistrationsController
skip_before_filter :require_no_authentication
before_filter :authenticate_user!
def new
puts "Method new was called"
super
end
end
skip_before_filter :require_no_authentication
before_filter :authenticate_user!
does not work any more.
Use authenticate_scope! instead.
How do I tell Devise to route the user to a one-time welcome screen when he has just registered?
Make a new controller "RegistrationsController" and customize the appropriate method:
class RegistrationsController < Devise::RegistrationsController
protected
def after_sign_up_path_for(resource)
some_special_page
end
end
If the account that is registered is not active yet, you have to override after_inactive_sign_up_path_for method.
class RegistrationsController < Devise::RegistrationsController
protected
def after_inactive_sign_up_path_for(resource)
some_special_page
end
end
Modify config/routes.rb to use the new controller
devise_for :users, :controllers => { :registrations => "registrations" }
Source: https://github.com/plataformatec/devise/wiki/How-To:-Redirect-after-registration-(sign-up)
In the Application controller, add this:
def after_sign_up_path_for(resource)
some_special_page
end
For most of Devise-related questions, hit up their Github wiki
by default Devise will forward user to: user_root (if your model name is user)
so you can define named route
get "/welcome" => "welcomes#index", :as => "user_root"
I am using Devise in my rails app. My Users model is registerable, which means that anyone can go to /users/sign_up and create a new account.
Is it possible to protect this route, so that only signed_in users can create new accounts?
Create a Controller with class Devise::RegistrationsController heriting. After you can add your filter. You just need define this controller like registration controller
class RegistrationsController < Devise::RegistrationsController
before_filter :authenticate_user!
end
In your routes.rb
devise_for :users, :controllers => { :registrations => 'registrations'}
It didn't worked for me because authenticate_user! is not getting called.
I fixed it that way :
class RegistrationsController < Devise::RegistrationsController
before_filter :prevent_sign_up
private
def prevent_sign_up
redirect_to new_user_session_path and return
end
end