How do I implement gradual engagement using Devise and Rails 3? - ruby-on-rails

I'm trying to implement a delayed-signup (aka delayed authentication aka gradual engagement) website flow using Devise + Rails.
By gradual engagement, I mean
"Don't make the user sign in until she
absolutely has to, but let her play
around and be remembered on the site"
I'm looking for a simple way to do this using devise. I feel like this is something many others have had to do, but I haven't found documentation on it.
The following approach sounds ok in my head, so I'm going to start with it:
Create users that are only "rememberable"
When certain pages are accessed, require that these users have more
data on them, like a username and
password, via something like
"before_filter :authenticate_user!" in
the appropriate controllers.
Does this approach make sense? Is there a better one? Do you have an implementation of a gradual engagement approach to signup/registration forms using Devise + Rails that you're willing to share?

I think the point of the article you gave us is to say:
only ask for sign up if necessary.
What does this mean?
Let's take an example. You're an e-commerce web site.
When does the customer has to sign up "at last"? During checkout. Never before. So you don't have to store, or remember anything about the user. Devise is never, never used here.
How do you manage the shopping cart of an unsigned in/up user? I'd say database, with session Id as primary key. Or You could store all the items ids in cookie, for later use.
In your code, if you have an action called checkout, just set in your controller a before_filter authenticate_user!, :only => [:checkout]
But maybe you have some constraints, like being able to keep your user's nickname without signing him up for example?

One alternate option is to do email-only signup, then send an email with a special link to finish registration later / bring them back to their account. There's an actively maintained tutorial on devise email-only signup at:
https://github.com/plataformatec/devise/wiki/How-To:-Email-only-sign-up
I've used this tutorial for a site I did a while back where we only asked for their email address to sign up, then later sent emails for them to complete registration / add a password.

You can keep all unsigned user's data in cookies, and transfer them to database once the user logs in, if you need to.

Related

Can I always require confirmation with Devise on Rails?

I've been asked to implement 2FA with email codes, like you get from Steam (and many banks), after you haven't logged in for awhile. I initially thought this would have been a flag I could turn on in the Devise config, but I can't find ANY place on the internet that talks about something like this. The desired process would be to generate and email a one-time pad to enter into a confirmation screen. Every reference I've found to 2FA with Devise refers to using things like SMS or an authenticator app.
Working within the framework of Devise, it seems like this might possibly boil down to unconfirming the user every so often, maybe like every other day. That way, the next time they log in, they get another email with a new link to "re-"confirm the login. The best I can find is Warden::Manager.after_authentication to set user.confirmed_at = nil, but this doesn't seem to be doing what I want.
Thanks to a friendly person on Github, I was directed to the Devise plugin, https://github.com/Houdini/two_factor_authentication, which does exactly what I wanted. I knew someone had to have already written it!

Ruby on Rails authentication without user name?

In all of my Rails applications I have a User model with name, email and password attributes (among others).
This seems to be the standard approach when building Rails apps.
The more Rails apps I build, the more I begin to wonder why the User.name is even necessary.
Wouldn't it be easier to just omit the user name everywhere right from the start?
From a user perspective, the sign up process will become easier. Instead of filling in four fields (username, email, password, and password confirmation), the user will have to fill in only three.
According to some usability experts this might increase the number of sign ups.
In addition to that, users will also have to remember less data, i.e. only their email address (which most people have memorized anyway).
So what might be negative implications of this approach?
I couldn't think of any so far.
You might need to make emails from your app personalized, maybe with greetings such as `Dear <%= username %>.
This doesn't mean you have to put name as one of the sign-up fields. You can put in the update form only, when the user edits their profile. Then you can make the edit_user_registration_path the after_sign_up_path_for devise.
I don't think using username is "standart" approach with rails apps. In fact, devise's vanilla approach is using only email on models.
However, being able to accept username or email has many other advantages. You may have other scenarios where users do not register at all. I mean, perhaps you are also creating accounts for users without any registration and you don't know their emails, if so using email will not be an option.
In some applications, we use more then 3 authentication strategies. Some users do not have a username or email at all..
In short, i think it really depends on your scenarios. But i am sure that using both email and username is not a rails convention.
If the main goal is a frictionless signup process then an OAUTH strategy would be the best way to go (4 fields of info down to two clicks), however you may want to collect the user info at a later time for a more personalized feel depending on what info you can capture from the callback.

Is there a Rails gem for management of a "multi-visit pass" scenario?

I'm a Rails noob. I'm looking to implement an application where users can purchase a multi-visit pass, then spend the credits week-by-week.
For example, register and login, then purchase 10 visits at a gym - the system should list 10 remaining visits. Sign up to a class and 9 remaining visits are listed. When the credits are low, remind the user to top them up with another 10-visit pass, etc.
I know I can use Devise and CanCan to manage the authentication and authorisation aspects.
My question is whether there's already a gem to handle the management of the user's credits, or whether I'd need to write this from scratch.
I've searched https://rubygems.org/gems/rails with no luck, but it's entirely possible I'm missing something obvious.
I don't think there is a gem to do that, but it should be pretty simple to code:
Add remaining_visits to your User model and table.
Do current_user.update(remaining_visits: current_user.remaining_visits+10) when a ticket is purchased.
Copy Devise sessions controller into app/controllers/devise/sessions_controller.rb.
Inside this controller, add this kind of code to create (where the user logs in): current_user.update(remaining_visits: current_user.remaining_visits-1).
Note: Instead of copying Devise sessions controller you can just overwrite the create action.

Devise, requiring user to accept terms of service?

I want to mandate that all users accept terms of service, much like is described here:
Ruby on Rails / Devise - Bypassing custom validation option in model when resetting password
However there are 2 requirements that make the above approach not fit.
1) Users are not self registered, rather they are created by a system administrator. The administrator obviously can't accept terms and conditions on the users behalf. The user should be prompted to accept terms and conditions on their first login.
2) If the terms and conditions change after the fact. Users need to re-accept the new terms on subsequent logins.
These seem like pretty standard workflows. Does devise provide any way to accomplish this?
If not, I am thinking this check will need to be implemented in a before_filter on my application controller. (Feels dirty mixing authentication with the application logic...)
Will I have to resort to this or can anyone suggest a better way?
Thanks
this is not something devise would handle and devise should not handle this because a TOS does not pertain to authentication.
What you could do is something like implement a state machine but that may be more complex than what you need.
The simple way would be to add a accepted_tos boolean field to your user model and tie that into a before_filter then you would set the accepted_tos to false everytime the TOS is updated.
Couldn't you theoretically just disable moving further in your app using JQuery?
Disable your form "continue" or "log in" button until they have checked a box or hit a continue button, then enable your log in button once they have.
If you need to store that information just make a column in your database on the user which gets posted too when they check the box or hit the continue button, or you could even utilize the number of log in counts as a way of knowing.
If user.logs > 0 then the user has already accepted the terms.
If user.logs == 0 then the user needs to accept the terms before they log in.
I guess according to your question it seems like tying everything into Devise sounds overly complex.
Hope this helps.

devise/cancan demo account

I'm using devise/cancan for my app and everything is pretty sound -- provided a user creates an account and signs in.
What I'd like to do is allow a user to get started without creating an account. And then sign up if they want to actually save their work.
Has anybody come across this before? Should I be figuring out how to create dummy accounts with devise? Or allowing unauthorized users access to creating models in my app via CanCan?
I could go into detail about how I've been thinking about approaching this, but it feels like a pretty obvious use case that somebody has come up with a nice solution for.
Thanks in advance,
Mike
If you go with creating dummy accounts, you would have to track the user somehow via a cookie and cache the values in that cookie in your db. Cancan does allow for guest accounts via the ability model. For example:
user ||= User.new # Guest user, for users who are not registered or don't have an account yet
Which is enough you to you started with applying permissions for non registered users. Note though, tracking by cookie alone is not very reliable and can lead to some type of security hazard (i.e. by means of cookie hijacking). User, one day, can also decide to clear out his cookies.
If need be, I would suggest letting the user do minimal interaction with a guest account and motivating the user to sign up / register with Devise as much as possible.
Hope that helps!
I actually am considering the same problem, I have a scheduling app that makes a calendar. To get over the problem I'm thinking that you use
user ||= User.new
Like was suggested above and using cookies to get the data to the database once the user creates an account.
This would mean that you would not have to worry about clearing out cookies because they would create an account if they want to save data.

Resources