Is Devise always a good choice?
I am building a contest/promotion app (see my other thread) and am now to the point at which I want to add users. I've used Devise in the past, and have also rolled my own auth system. I like the control of doing things myself, however, Devise saves a lot of time. Is Devise always a good choice? Or are there situations in which it's not desirable? (If so, are there good alternatives?)
From my perspective, I always use Devise and then make my overrides to it as necessary. The reason for that is because Devise is very well tested. I think it's much more likely that implementing our own auth systems is much more likely to have subtle mistakes and security vulnerabilities than going with Devise first and then customizing it. It gets constantly updated and is tested by thousands of developers and users all the time whereas my custom system is unlikely to get security tested that often.
That's my reasoning for using Devise as the basis and then customizing it. You're probably fine going with any system you want including rolling your own, but you'll want to keep in mind the more testing, the more secure it will be.
That's good to know. I guess I will spend my time learning the ins and outs of Devise instead of rolling my own. Thanks for your help!!
Hey Chris, I actually have another question related to this one. In my app, I want users to be able to sign up and create their own promotional contests. However, I will also have users sign in to the app to enter the contests that other users create (I will be doing this through Facebook/Twitter OAuth). What would be the best way to structure this? Should I create a User and an Admin model in Devise? That way I'd have the User model for users who log in with facebook/twitter to enter a contest and the Admin model for users who actually create the contests. I guess I would then use Pundit or another auth gem to have different levels of Admin users (I would be the ultimate admin and other users would only be allowed to edit their own contests). Does this sound reasonable? I don't have much experience with this so I'm not sure the best way to build the functionality. Let me know how you'd structure this! Thanks!
That's a great question. Do you think you want separation between your account as a contest creator and as a contestant? It may be easier to manage to separate them by doing something like Admin and User, but it might also be confusing. If I create an Admin account and then click on someone else's contest, I would have a separate User account from my Admin one without realizing it. That might work fine for your application, but I just wanted to see if you had any reason to keep them connected.
If you keep them connected, you could connect the Twitter & Facebook accounts to a User, skip the Admin model, and then allow contest creators to attach their Facebook and Twitter accounts so they can see both the contests they created and the contests they are a contestant in. Depends on what you're going for here.
Do you have any preference either way?
No, I don't have a preference. I am just looking for the best way to structure it. I do think it would be less confusing and easier if people were able to have one account (Just a User model), and then I would use an auth gem to set roles for each user. Does that sounds like a good way to set it up? If so, what auth gem would you recommend?
That's probably what I would do. I'd have a single User model, authenticate with Devise, and use Omniauth's Devise integration to manage that Facebook and Twitter login.
With Facebook you get an email, Twitter doesn't give you one. Since you basically need a User as the main account for everyone, you'll need to ask for an email (and preferrably a password) after they login with Facebook or Twitter. You can prepopulate with Facebook's email and leave it blank for Twitter. The user can then confirm this is the email they want to use on their account (and optionally a password).
Then you can create their User record, save their Twitter or Facebook account as an associated model to the User. I usually call this Service.
class User has_many :services end
class Service belongs_to :user end
And your Service would store things like the social network name, their username/ID on the social network, and any other metadata like their avatar url.
That way they can then sign up with Twitter or Facebook but you've also got an associated User record.
Signing up as User first and then being a contestant means that you simply look up the User with the email they provided and associate the Twitter/Facebook account with it instead of creating the User.
Ok, I'll give that a shot. Thanks! Also, would you recommend Cancancan or Pundit for authorization? (or something else)
My preference is Pundit over CanCan because I find it clearer to understand what's going on.
I just played around with Pundit and it's awesome!! I love the default "lock everything down" out of the box. Thanks for the recommendation!
Glad you like it!
I found another one recently called action_access that looks to have a wonderful API but I've never used it before. Hope to do a screencast on it soon.
I jumped on this thread late, but I would highly recommend Devise. As Chris said, it's well tested, very mature, and feature rich. As well if you really want to lock things down you can use the Devise Security Extensions. It also plays nice with CanCanCan and/or Pundit.