I was recently tasked with a project where users could connect their account on our application to Github using OmniAuth. As I was looking into the implementation, I was surprised that the documentation was little bit mix-and-match. Find a little bit of info here, a little bit more there, and then the whole picture comes together.
I thought to myself, wouldn’t it be nice for all of this to live in one place? So here it is — my attempt to combine everything you need to know about getting started with implementing and testing OmniAuth in a Rails app.
Step 1: Add the gem to your Rails app Gemfile. For the sake of this tutorial, we’ll be using gem ‘omniauth-github’. Don’t forget to bundle after!
Step 2: Set up your OmniAuth configuration. In config/initializers, create a file called omniauth.rb. Here’s what we put in our omniauth.rb file to set up our configuration:
Now our application is aware that Github is our provider, and that it needs to reference our specific Github Client Key and Github Secret Key. In order to get these 2 important credentials, you’ll need to register your app on Github.
Sign in to Github, then in the top right corner of the page, click on your profile picture and select Settings. From here, click on Developer Settings, then New OAuth App.
Fill out the form with your Application name and Homepage URL. To make things easy for myself, I actually registered for 2 different apps, 1 for my test environment and 1 for my production environment. This allowed me to seamlessly test in my local environment, then push to Heroku without having to modify my OAuth application each time.
The last part to complete is the Authorization callback URL. We’re going to set this up as /auth/github/callback.
So in sum, here’s what a test environment registration looks like:
Once you’ve registered your application, you’ll be taken to a page that displays your Client ID and your Client Secret. Now you’ll need to input these into your Rails app. These keys should never be hard-coded anywhere in your application. That’s a good way to get your keys revoked faster than you can type ‘git push origin head’.
Let’s use a gem called ‘figaro’ to keep everything kosher with our Github keys. In your Gemfile add gem ‘figaro’. In your terminal, ensure that you’re in the root directory of your Rails app, and run ‘figaro install’ from the command line.
Back in your Rails app, within the config folder, you’ll notice that a new, grayed-out file called application.yml has been created.
You’ll see some commented out information within this file. I simply added my keys (with some dummy directional copy instead of my actual keys, because security) on at the bottom of the file as such.
Now your omniauth.rb file knows what ENV[‘GITHUB_CLIENT_ID’] and ENV[‘GITHUB_CLIENT_SECRET’] means without risking that your credentials will be revoked.
Step 3: Add a link in your view for users to access this new authentication. In our application, our users can register for an account by email address. Once they visit their dashboard, they’ll see a link to Connect to Github*.
*There will be cases where you’ll create a new account with OmniAuth, but I wanted to make the important distinction that we’re doing something a little bit different here.
Step 4: Add your login path and callback url to your routes.
The callback route is where that distinction I mentioned above becomes important. If you’re creating a new user, you may want this to go to ‘users#create’, or if you’re logging a user in, you may want to go to ‘sessions#create’, which is actually the default route if you don’t tell this callback URL where to go.
Since we’re updating an existing users info, not logging them in, we wanted this to have its own home (👋 hi Single Responsibility Principle!). So we sent it to an update method in our Sessions Controller — this way we could leave ‘users#update’ open for future functionality if we wanted our users to have the ability to update their account information.
Step 5: We finally get to call OmniAuth! request.env[‘omniauth.auth’] will give you everything you need to know from this authorization handshake. What you choose to do with it from there is up to you.
We wanted our user to see their Github information every time they logged-in to our application, so we decided to create a column called access_token in our database.
Now that we have our user’s access token, we’re free to utilize that info when making API calls to Github.
So how do we test that all of this is working? It was important for us to know that this process was not only successfully retrieving the access token, but updating the user’s account as well.
Step 6: OmniAuth has a handy testing setup where you can indicate that you’re in a testing environment and create a mock hash that you would expect to receive from whatever provider you’re using.
Using RSpec, we set up the test with a before(:each) to create our test environment and our hash:
You’ll notice we integrated ENV[“TEST_KEY”] here, which obscures my personal Github token. That way we can simulate a legitimate Github OAuth handshake with my Github account, but not share ALL of my secrets on the internet.
Now we can create the rest of our feature test by creating a new user, logging them in to our application, visiting their dashboard and clicking on the “Connect to Github” link. The OmniAuth test environment will circumvent the interaction and instead of going through the real OAuth process, it will return my hash above. As our final check, we can assert that our newly created user that clicked on the “Connect to Github” link has been updated to have our obscured Github token.
And it passes!
I hope this helps others who are looking to get started with OmniAuth. If you have any feedback about how we chose to tackle this problem, or you think there’s a helpful tidbit of information I can add, feel free to let me know!
Interested in checking out the project I was working on? You can find our repository here: https://github.com/jalena-penaligon/brownfield-of-dreams or our production site here: https://fast-sea-29858.herokuapp.com/