Implementing auto login on 'confirmation mail click' with Devise - ruby-on-rails

We use devise on our rails app in order to deal with sign-in and authentication. Basically, the process is quite straightforward: you sign up, get the confirmation email with the link pointing to a route such as path/page/confirm/token. Once authenticated, the user is redirected to page/login in order to enter his login/password and access the service.
Right now, we would like to login automatically the user that clicks this link right after he reaches the page/confirm/token.
I've been investigating, and it seems like a method that was initially used by people after devise 3.1 to have this behavior:
config.allow_insecure_sign_in_after_confirmation = true
I was planning to use this in the initializers/devise.rb, but unfortunately it also seems like it have disappear from devise methods, I ran these commands on console to check:
gem install devise
pry
require 'devise'
Devise.methods
... no allow_insecure_sign_in_after_confirmation method there.
I might try to do this manually in the confirmation controller with something custom like:
def show
u = User.find_by(confirmation_token: params[confirmation_token])
sign_in(u)
end
But unfortunately, again, it's not working as expected.
Any input is appreciated.

Related

Ruby on Rails User Login Event

I'm using devise for user authentication. I would like to create a component to be able to respond to a user logging in. Does devise have user events or something similar?
You can check out the pages here: Devise Wiki Pages. You can do things like redirect to certain pages. Additionally, when someone is logged in, so you can always check the current_user method provided by devise and see if it returns nil or a user.
Specifically look at redirecting on signin/signout. You can redirect to a controller action that does what you want.

Rails + Devise + API + User Registration

I am new to ruby and rails and so far I managed to setup user management using devise. Right now I am trying to integrate support for mobile Android and iOS apps. So far it is possible for them to login and logout and get an authentication token. But in addition to that I would also like them to be able to register.
Now, as I understand it I have to do a post to
http://localhost:3000/users/sign_up
How does this post look like? And how do I get a JSON response? I found this on stackoverflow.
"utf8=✓&authenticity_token=n5vXMnlzrXefnKQEV4SmVM8cFdHDCUxMYWEBMHp9fDw%3D&user[email]=asd%40fasd.org&user[password]=321&user[password_confirmation]=1233&commit=Sign+up"
Unfortunately this does not work - I am getting the message "Bad request". I also do have a couple of questions about this example. What is the authenticity_token for? How do I get one? This is not the devise token authentication I guess as the user is not even in a position to have one at this point.
Also, after a successful login I would like to bundle the "registration successful" message with a generated devise authentication token. So I guess I have to somehow extend devise`s existing registration controller.
Thank you very much in advance!
Devise already has all this setup. Based on your signup path, I infer that you mounted Devise onto http://localhost:3000/users. Devise includes all the controllers and views that are required, including the log in form, the sign up form, the email confirmation form and the password reset forms.
GET http://localhost:3000/users/sign_up is actually a form for users to signup at. The form on that page will POST to http://localhost:3000/users/, which goes to Devise's registration controller's create action.
Assuming there is no action/view already at /users/sign_up, the sign up form should be there, go check if it is there (assuming you set up devise_for correctly in your routes.rb file).

Devise with user logged in using multiple scopes logs all but one out when using token_authenticateable

I'm using Devise with multiple scopes (in this case, a user scope and an admin scope) and admins are able to 'become' a user using the approach on the Devise wiki. This works well, except that I have one particular page that requires the use of an auth token that causes a problem with a session logged in under both a user and admin scope. The page generates a POST to a controller that requires a user to be logged in using the user auth token. The POST succeeds, but afterwards, the admin scope has been signed out. (Meaning that admin_signed_in? returns false.) Other pages that execute POSTs to the same controller without requiring the auth token work as expected without logging out the admin scope.
I suspect that something is going on with token_authenticatable where the authentication of any scopes other than the one associated with that specific token are logged out. I've searched for references in the devise gem source to both the devise sign_out and warden logout methods that could be invoked as part of the token_authenticatable functionality and wasn't able to find anything.
This is happening with Devise 1.3.4. Any help is appreciated.
In case anyone else is looking for a solution to this, I found that the before_filter/after_filter approach I described in the comment to my question seems to work fine. I think that a better, more general solution to this would be to make a change to the devise gem and underlying calls to warden, but didn't have time to make those changes for this particular problem yet.

Exception with Devise is password is nil

I want users to interact with my site without having to create an account and then later create an account (supply password, name info..etc) if they want more.
This works fine but if user thought they've created an account and then tried to login (likely using a password they use all the time) Devise will through an Exception:
BCrypt::Errors::InvalidHash in Devise/sessionsController#create
Because password is nil. If they go through the signup and then signin again, it works.
I'm using devise (1.2.0), Rails (3.0.4) and Ruby 1.9.2
I mean I can go around it by creating a dummy password and have a field to say if the user has signed up (or check if other mandatory fields have been provided) then resetting the password on actual sign up but I think in all cases it shouldn't through the above exception.
Is there anything I can do/set to go around the problem?
The easiest way is probably to just generate a random one, using something like Devise.friendly_token[0..20] but you could also override the Devise controller and method for logging in, rescue the exception, and just redirect.

Delay and or resend Devise's confirmation email for manually created users

I'm using Devise to allow user signup as-well-as using my own user admin to create users manually. When I create a user in the admin, Devise sends a confirmation immediately to the new user. I believe this is due to the fact that both devise and my admin use the same model. How do I delay this email until the administrator is ready to send it?
Additionally, Devise's validation is requiring the admin set a password for the new user. I would much prefer the manually created users specify their own password when they respond the confirmation. Right now manually created users will not know their password unless I send it too them in a supplemental email.
#user.skip_confirmation! confirms the user, so the user can log in
without using the confirmation.
This works for me in devise 3.5
Stop devise to send confirmation email while creating user.
#user.skip_confirmation_notification!
Send confirmation instructions later
#user.send_confirmation_instructions
We do this in one of our apps. You can tell Devise NOT to automatically deliver the confirmation like this:
#user.skip_confirmation!
And then later, you can do
Devise::Mailer.confirmation_instructions(#user).deliver
For Rails 2.x you'd do something like:
DeviseMailer.deliver_confirmation_instructions(#user)
The solution is not so simple as #Ryan Heneise's answer. If you do #user.skip_confirmation! it confirms the user, so the user can log in without using the confirmation, so the confirmation letter in this case is useless. This solution does not allows the user to log in without the confirmation: Rails 3 with Devise for Authentication - How do I manually create a user?
There's now an easier way (was added back in v2.2.4)
Devise's confirmable module now includes the perfect skip_confirmation_notification! method which allows for a cleaner solution:
#user = User.new params[:user]
#user.skip_confirmation_notification!
#user.save
# ... do stuff, then later...
Devise::Mailer.confirmation_instructions(#user).deliver
I just spent some time looking into this, basically you just need to add this and setup delayed_job.
def send_confirmation_instructions
generate_confirmation_token! if self.confirmation_token.nil?
::Devise.mailer.delay.confirmation_instructions(self)
end
Add it in your user model as protected method to override the devise one in confirmable. Also, note the gem was just updated to add a new method to be overridden on create that sends the confirmation instructions.
There is now the devise-async project:
https://github.com/mhfs/devise-async
https://github.com/plataformatec/devise/wiki/How-To:-Send-devise-emails-in-background-(Resque,-Sidekiq-and-Delayed::Job)
Do you use delayed job ? It allows you to define single methods for delayed run.

Resources