I am using Rails 3.2.2 and Devise 2.0.4 with token_authenticatable turned on and everything work well. Now I want to do the following
When a user logs in or logs out reset_authentication_token for the users
For this I need to override the SessionsController but I dont know where to put the call to reset_authentication_token
(Note I want this only when a user is successfully logged in or out)
You can override the sign_in helper of Devise in ApplicationController:
def sign_in(resource_or_scope, *args)
super
current_user.reset_authentication_token!
end
Related
I am using Devise gem for Authentication and ActiveAdmin gem which also uses Devise gem as dependency. I want to enable 2FA for ActiveAdmin, that's why I want to over ride after_sign_in_path_for method. I am able to over ride the method in ApplicationController but doesn't sounds right to me because this will affect our normal login as well. Is there any way to over ride after_sign_in_path_for only for ActiveAdmin. Currently this is how I am doing
class ApplicationController < ActionController::Base
def after_sign_in_path_for
end
end
If I can't only over ride only ActiveAdmin controller then how to deal with normal login without 2FA and ActiveAdmin login with 2FA. Something like this.
class ApplicationController < ActionController::Base
def after_sign_in_path_for(resource)
if resource.instance_of?(AdminUser)
redirect_to setup_2fa_path
else
super # <-------- is this possible or is this correct ?
end
end
end
There must be a way where I can only over ride after_sign_in_path_for for ActiveAdmin. Or do I need to over ride ActiveAdmin::Devise::SessionsController class in initializer? Putting controller login inside initializer also don't feel right to me.
UPDATE
I noticed there is one more problem, when control reaches after_sign_in_path then current_admin_user is already set. This is problem because user can skip setting up 2FA and type path in browser like localhost:3000/admin and they are in because there is current_admin_user. I can set current_admin_user to nil in after_sign_in_path but I am not sure if that will open door to other type of attacks ? How should I deal with this ? or shall I try to over ride different method ? I don't know if there is something like before_sign_in_path_for or something else.
An approach is to open up and extend the Devise::SessionsController within ActiveAdmin. I managed to implement 2fa with a one time password based on code discussed at https://medium.com/#acesubido/adding-two-factor-authentication-in-activeadmin-2ed134b60042 and https://medium.com/#acesubido/part-2-adding-two-factor-authentication-in-activeadmin-cc5eab67057c
Also: https://blog.kiprosh.com/adding-two-factor-authentication-2fa-for-activeadmin-auth-in-a-ruby-on-rails-web-application/ can be of inspiration, I chose for the first setup with a 2 step process. Also you may want to consider a before_action in you ApplicationController that allows for users to setup their 2fa after logging in:
def check_2fa
return if current_admin_user.nil?
redirect_to user_dashboard_two_factor_new_path \
if current_admin_user.force_2fa && !current_admin_user.otp_required_for_login
end
Good luck.
I am using devise for authentication, devise automatically sign in after signing up,
i need just sign up but not sign in.
There is similar question link but it didn't help me
Disclaimer: The following code is not verified in my practice. Just in theory they are likely to work.
At first you need to use your custom RegistrationsController. You can check how to do that in Devise wiki.
After setting up, things are fairly easy. Do the following in your custom controller
class Users::RegistrationsController < Devise::RegistrationsController
def create
super #Nothing special here.
end
protected
def sign_up(resource_name, resource)
true
end
end
How does it work? In Devise's code, #create will call a protected method #sign_up after saving successfully. This method does nothing but sign in the user. What we need to do is to overwrite this method to stop that action. Of course you can even add more of your logic here if necessary.
I have overwritten after_sign_in_path_for in my application controller as follows:
application_controller.rb
def after_sign_in_path_for resource
case resource
when User
blah
when Admin
blah
end
end
This works when the user signs in via the sign in page. But after_sign_in_path_for method doesn't get called at all when a user is signed in via Devise's Token Authenticatable module. The user gets taken to the root_path. How can I change this?
I'm using Rails 3.2.0, ruby 1.9.3p194 and Devise 2.1.2.
I would advise you to take a look at Devise's own ConfirmationsController, it looks to me like its calling after_sign_in_path_for, and the resource would be user I would assume. But it may take overriding that Controller with your own, so you could log the resource before you'll know for sure.
I am using devise gem in a rails application with multiple subdomains. Each subdomain is handled by respective controller, which look like this:
class Subdomain1Controller < ApplicationController
before_filter :authenticate_user!
def index
end
end
With above controller implementation, Devise always keep subdomain while redirecting user to login page. In above case, Devise redirect user to http://subdomain1.acmesite/users/sign_in instead of a common sign_in Url.
This leads to having multiple sign_in urls for each sub-domains.
http://subdomain1.acmesite/users/sign_in
http://subdomain2.acmesite/users/sign_in
http://subdomain3.acmesite/users/sign_in
I am wondering if it's possible to override devise method to exclude subdomain part from the url and yet keeping the previous page url information. More preciously, I wants Devise to redirect user to a specific Url (like: http://acmesite/users/sign_in) irrespective of subdomain and after successful authentication, Devise should return user back to the caller subdomain+page.
You need to write a custom FailureApp which kicks in when the user is unauthenticated.
From How To: Redirect to a specific page when the user can not be authenticated
class CustomFailure < Devise::FailureApp
def redirect_url
#return super unless [:worker, :employer, :user].include?(scope) #make it specific to a scope
new_user_session_url(:subdomain => 'secure')
end
# You need to override respond to eliminate recall
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)
I droped Devise gem from my project and now using Sorcery instead.
Sorcery provide me complete control over controller and view, fully comply with my project requirements. With six months running on production after this transition, I am happy with Sorcery gem.
How to redirect to a specific page on successful sign up using rails devise gem?
This page is for you: http://github.com/plataformatec/devise/wiki/How-To:-Redirect-to-a-specific-page-on-successful-sign-in
I hope its not too late, you need to override the after_sign_up_path_for of the registration controller, create a registrations_controller.rb in your app/controller, and override said action.
registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def after_sign_up_path_for(resource)
...path of choice...
end
end
haven't tested this code so might not work with just copy and paste.
If you look here it will give you the actions for any other redirects you made need.
https://github.com/plataformatec/devise/blob/master/app/controllers/devise/registrations_controller.rb
The wiki page recently moved and the info is here:
https://github.com/plataformatec/devise/wiki/How-To:-Redirect-to-a-specific-page-on-successful-sign-in-and-sign-out