How great is it not having to create and remember the username/ passwords for the many different sites we visit on a daily basis? Logging in with pre-existing or third party accounts (most common, Google, LinkedIn, Facebook, Twitter…) has become an increasingly popular feature in modern day web applications. Instead of having to create a new account or logging in with the specific username and password tied to that application, nowadays users can simply opt to sign in with their Google/Twitter accounts.
Most, if not all, of us have seen or used this feature. In this post I’ll be discussing the technology that makes it all possible: OAuth!
What is OAuth? OAuth or Open Authorization is a system that allows third-party services to exchange your information for authorization. Etsy, for example, allows its users to sign in using Google/Facebook/Apple’s authentication system.
To make use of Open Authorization or OAuth we can use packages such as OmniAuth (OmniAuth-OAuth(2)). OmniAuth is a Ruby package, or gem, for supporting decentralized authentication in Rack-based (Rails) sites. Byway of JSON Web Tokens, OmniAuth asks the identity provider* for access to the user’s information, then responds with a hash in the form of request.env[‘omniauth.auth’] containing all of the user’s information. This information can then easily be passed onto a database using something like Active Record to create a new user or to compare against existing records (when logging the user in).
*For a current list of OmniAuth authentication providers (better known as strategies) visit: https://github.com/omniauth/omniauth/wiki/List-of-Strategies.
The OmniAuth flow:
1 - A new user tries to access a page that requires them to be logged in. They are redirected to the login screen. The login page offers the options of creating a new account or logging in with Google.
2 - If the user clicks Log in with Google they are redirected to the Google sign-in page (through the appname.com/auth/google route).
3 - If the user is already signed in to Google, Google simply asks if it’s okay to allow access to their information. If they are not, they sign in as they normally would.
4 - Lastly, the user is then redirected back to the app via the appname.com/auth/google/callback route to finally access the site.
To show how to incorporate OAuth in your Rails applications I’ll use my Giving-Back project as reference…
- To start, add the omniauth and omniauth-google-oauth2 gems ( I decided to use Google as my third-party auth provider/strategy) to your Gemfile and run bundle install.
- Next, you’re going to need the following two pieces of information from Google: an application key and secret. This will help identify our app to Google.
To set these up:
- Visit https://code.google.com/apis/console/
- Click on the create a project button
- After creating a new project, open up the project, click on credentials found in the APIs & Services tab under the navigation menu on the top left side, then on OAuth consent screen. The consent screen is what is shown to users when requesting access to their data via your client ID; you’ll need to input your: app name, user support email, email address(es) for Google to notify you about any changes to your project.
- Next, under the credentials tab on the left side, click on create credentials then OAuth client ID, select the type of application then proceed to creating the client ID. Do the same for the client secret.
3. To set up our app’s OAuth credentials. Start by creating a file named config/initializers/omniauth.rb and include the following lines:
Rails.application.config.middleware.use OmniAuth::Builder do provider :google_oauth2, ENV['GOOGLE_CLIENT_ID HERE'], ENV['GOOGLE_CLIENT_SECRET HERE']end
***Important: (dotenv-rails) Instead of including your environment variables directly in the local ENV hash, risking potential exposure of these variables, consider using dotenv-rails; dotenv-rails is a Ruby gem that ensures our variables are loaded into our ENV hash in a safe and secure manner.
To use dotenv-rails:
- Add dotenv-rails to your Gemfile and run bundle install.
- Create a file named .env at the root of your application.
- Add your newly acquired Google app credentials to the .env file.
- Last and most importantly, make sure to add the .env file to your .gitignore file to ensure that you don’t accidentally commit your credentials.
4. Now all we need to do is create our “Log in with Google” link that will initiate this process.
When clicking on a “sign in/up with [PROVIDER]” button a GET request is sent to the …/auth/PROVIDER route. OmniAuth intercepts this request redirecting it to the PROVIDER’s login screen. Upon successful login, the user is redirected back to the OmniAuth route with new access to the site.
In addition to helping create a seamless user experience, OAuth allows us to put the burden of protecting our users’ passwords on someone else, someone like Google. Remember Rails security measures do not extend to your servers where hackers can potentially intercept requests, therefore a little help from someone like Google is greatly welcomed.
Thank you OAuth! Thank you OmniAuth!