In this article I’ll detail the process of logging into google via the
Omniauth Gem.
I set up my code almost the same as how my teacher, James Dabbs
at The Iron yard. Also keep in mind that devise
is needed to be setup before omniauth will work.
Getting Set Up
The first thing we will do is add of the gems and gem dependencies we’re going to need for logging into google. There are two gems that are going to be needed. The first is the actual Omniauth Gem and the second can be found on the list of provider gems that are supported with Omniauth. I decided to use the google-oath-2 gem.
1 2 3 |
|
Note: Always run bundle after changing your gemfile
Note: I’ll go into the purpose of Hashie in the identifier section
Next we will bundle our gems for use.
1
|
|
Note: bundle is shorthand for bundle install.
Configuring Devise
Next we need to configure devise to let it know that we are using omniauth, and let it know where to put our API key and secret token.
1
|
|
Note that in this case we are using environment variables.
It is not wise or safe to put any type of api keys, secrets, or passwords
live on the internet.
I suggest using the Figaro Gem
to store environment variables for easy deployment to heroku.
Now we actually need te data to store in the (in this example)
‘GOOGLE_ID’ and ‘GOOGLE_SECRET’.
Getting Key and Secret from Google
The Google Console is the starting
point. Through here you go through the process of creating a new project.
I’m not going to go into the specifics of what to click because it is pretty
straight forward, but I will cover the crucial information that is
needed.
Once the project is created, under the tab API’s & auth select API’s and
turn on Contacts API and Google+ API.
Next, under the consent screen select an email-address and enter
a product name. THIS IS IMPORTANT.
The product name cannot be the same name as the project name (which
can be seen on the top left corner of the console).
Lastly we’ll configure the credentials.
Since all I’m going to use is for development I’m going to put in
the url’s as http://localhost:3000. If you’re going to deploy to an online
website, add the same url’s as I’m going to add, but replace
localhost:3000 with (for example) ‘http://yourwebsitehere.com’.
Under Javascript Origins enter in http://localhost:3000.
Under Redirect URI’s enter http://localhost:3000/users/auth/google_oauth2/callback.
Keep in mind, the callback gave me a lot of trouble while setting up.
Various blogs never had the same callback.
This one worked for me because google told me to use it!
I got this information when I got to the point where I was trying to
login with google and on the 404 page it said it couldn’t find
that url as a redirect uri.
If yours is different, add it onto the redirect uri list and prosper.
Finally we can copy the Client ID as the GOOGLE_KEY and Client Secret
as GOOGLE_SECRET.
Again, see my Figaro
blog post onto how to add in the two.
Continuing Devise Setup
Now we need to setup the routes so devise knows how to handle the omniauth callback requests.
1
|
|
Note: My devise model is named Users, yours may be different.
As you can guess sometime soon we’re going to make a controller called
omniauth_callbacks. We’ll get to that soon, first we need to
let the devise model know that our app is “omniauthable”.
1 2 3 4 5 |
|
Note: Again, my model is user.rb, yours may be different.
Also, note the addition of omniauthable.
Configuring the Callback Controller
Now we’ll go ahead and setup the omniauth callbacks controller. This controller will inherit from the devise:omniauth callbacks controller. Essentially, we’re adding methods for each provider. Each method is named after the provider. In my implementation, I’m setting it up where it is easy to add multiple providers, the only line that will need to be edited after adding an additional provider is the array list of providers.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
One thing may stick out as being odd. The Identifier.new hasn’t been defined yet. Next we’ll create a service called just that with the purpose of managing the creation of identities (a model which we will also set up). The general idea is a User has many identities. An identity being the providers themselves. With this setup, a person can sign into google, amazon, or whatever and maintain the user.
Creating the Identifier Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
It would take a while to type out what each individual method is doing. Hashie::Mash is from the hashie gem. Essentially, it allows the use of the dot syntax from returned JSON and not having to use the bracket syntax all the time. You’ll see a lot of talk of identity. It may feel awkward because we haven’t defined the Identity Model yet. Take note of the resolve method which was called in the omniauth callbacks controller. On the creation of an Identifier we pass in the current_user and the data generated from the provider to check and see if the user exists with another provider and if that provider has already been created. If it hasn’t been created, it is and if not then it returns the provider.
Creating the Identity Model with Relationships
Next we need to create the Identity Model and relate it to the User.
1 2 |
|
Now that the model has been created and migrated, lets go ahead and set up the relationships.
1 2 3 4 5 6 |
|
Note: This is for the User Model.
Now the Identity Model will have a bit more complexity.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
There are a few things going on here. The relationship connection, validations, serialization to json, and creating methods. Now we can call things like current_user.identities.first.provider Which will return “google_oath2” if it was your first sign in (since identities returns an array). Likewise, current_user.identities.first.auth_data will return all of the data from google. I can see keys such as first name, last name, email, images and more!
Calling the Sign in with Google Link
If you look in ~/apps/views/devise/shared/links.html.haml (I’m using haml). There is this line of code at the bottom.
1 2 3 |
|
If you click on the normal devise sign in route, you’ll see that sign in with google was automatically generated for you. If you want to add your own custom link on a given page, use this link.
1
|
|
Conclusion
With this lies the completion of connecting to google using the omniauth
gem.
The purpose of this tutorial was to allow the addition of other providers
with very few lines of code.
Lets say for example you were wanted to add facebook.
You would need to add the omniauth-facebook gem, add the config under
devise.rb, create the api key/secret from the facebook developers page,
setup the redirect uri callback from facebook,
log that information into application.yml (if you’re using figaro), and
finally in the omniauth_callbacks controller add :facebook to the
array of providers.
Something like facebook is easy to integrate with the current setup.
There are a couple of providers that aren’t so easy.
Twitter and Linkedin don’t return email addresses in their auth_data.
Since devise requires email I’m sure you can see the hassel.
Some strategies are to after clicking the sign in with twitter button,
have them fill out a quick form for email, or to randomly generate an
email for them.
Either way, good luck and happy coding!