Don't use devise
Adding a second type of authentication to our web app was a lot easier without using Devise, the rails authentication method :has_secure_password? is breifly explored.
Running Mixtable, we found a sticking point that deterred some potential customers from signing up to the service, Facebook authentication. To remedy this we embarked on adding email/password authentication to web app. The site was already configured with the omniauth gem to provide facebook authentication.
Initially I looked into Devise to handle both oAuth and password auth concurrently. Devise is a heavy gem and takes a lot of control over how you handle your user records. In return it gives you everything you need for password authentication like password reset links etc. Trying to integrate Devise resulted in a mess. It would have taken a lot longer to modify our database to play nicely with Devise. We had very tight release schedules at Mixtable and wanted to get mvp’s of new features deployed quickly so we could start getting feedback. Plus I was learning Ruby on Rails at the time, and found this from a Stack Overflow answer: ‘You will learn a lot of good things from it [proprietory auth], and using Devise will cause you to miss a lot of great information.’ Which after the pain in the arse Devise was, sold me.
Since we had email verification and session management already setup without using devise, configuring :has_secure_password was sufficient. This is a cool Rails method which makes building password authentications a doddle. It basically takes the cryptic bit out of it, and who wants to mess around with that? This tutorial is great at describing it's basic implementation.
To differentiate between Facebook auth and password auth users, an 'fb_user?' column was added to our Users table. All users Facebook data was stored in a Facebook Data table, with duplicates of the data we used in a User Profiles table. Non Facebook users didn't have the entry in the Facebook Data table. The has_secure_password method has automated validations, since Facebook users didn't need these validations, the automated password validations were disabled and handled with conditional validations.
Devise also handles logging users in and out, this is handled with Omniauth in our Session's controller. For the password authentication a form_for was added into a partial which could be dropped in any where on the site that required a log in box.
We implemented a helper method to handle session variables called current user. The most useful method being the signin:
This is called from either the Omniauth call back or password authenticator method. It can also be called from other controllers to allow users to log into their user areas from email links. So for a password recovery email for example. Has_secure_password and the current_user.rb helper made a very satisfying replacement for devise. They provided a lot more flexibility which we needed for the speed at which the web app changed.