Software Developer, Cyclist, & Traveler.

Authentication with 37Signals' OAuth and omniauth-37signals for your Rails application

First you'll need to register your application so that you can obtain your 37Signals client credentials. I recommend setting the redirect URI to http://127.0.0.1/users/auth/37signals/callback so that you can test it locally if you need to. If you're using pow.cx you can specify that symlink as the default and easily test your OAuth integration. Even better if you're using the powder gem you can just run "powder default" from the app root and it'll link that up as the default app which will then respond at 127.0.0.1.

Next you'll need the omniauth-37signals gem. I'm using Devise with Omniauth support so I'm going to assume you're doing something similar. Your Gemfile should have the following in regards to devise/omniauth, upgrade versions as needed:

gem "devise", ">= 2.2.3"
gem "omniauth-37signals", "~> 1.0.5"

Run bundle install to install the new gems and then run "rails generate devise:install" to create the default devise.rb initializer file. Then configure the omniauth provider for 37Signals:

You'll probably want to setup a model to interact with devise, go ahead and run that next "rails generate devise User email name". This will generate the User model as well as bunch of other relevant files and methods for interacting with your user. Typically you'll want to authenticate with multiple OAuth providers, the easiest way to do this is to create a Authorization model which will store the relevant OAuth provider's details:

Make sure you set the oauthtoken and oauthrefreshtoken as text columns, they use pretty long keys and they usually get truncated on accident if you use a varchar. OAuth tokens from 37Signals also expire after a given amount of time, they provide this date in the returned authentication details so we'd like to store that for future reference. The oauthrefreshtoken is used to obtain a new oauthtoken without needing to prompt the user to go through the OAuth process again, if we wanted to we could just run a background job to refresh tokens that are about to expire.

After you've done that make sure to migrate and then setup your models with the following settings:

devise_scope :user do
# Normally the provider is mapped back to an action such as :facebook mapping back to the "facebook" action within
# the controller. Since we can't name an action "37signals" we have to map it to a method name that is allowed.
get '/users/auth/37signals/callback' => 'users/omniauth_callbacks#thirty_seven_signals'
end
devise_for :users, :controllers => { :registrations => 'registrations', :omniauth_callbacks => "users/omniauth_callbacks" }

Once you've setup all of that the last thing to do is just provide a link to get them connected to the OAuth dialog box by using "useromniauthauthorize_path('37signals')".

If you want to test sign in via OAuth and the 37Signals provider then you can use the add_mock method. If you place this in features/support/omniauth.rb it'll load and take over whenever you hit the OAuth URLs to properly return the specified hash.