Rabid Logo

Rabid is now Ackama

In September 2018, on the company’s 8th birthday, Rabid became Ackama - this was to reflect that fact that we work on large digital ecosystems, and given that nature is the largest ecosystem in the world we wanted a name that came from nature. Ackama, or Makamaka, is a small bushy tree with white flowers and red seeds. It’s found on the coast from Whangarei north.

Go to the Ackama blog

Using omniauth-google-oauth2 for Google OAuth2 with Ruby on Rails

I tried doing this manually using the oauth2 gem, but while it kind-of works, getting any sort of user information requires you to decode a JWT payload (ugh, OpenID why does Google no longer support you).

Instead I got it working with just the omniauth-google-oauth2 gem. Based on this tutorial which is for an older version of Rails:

1. Add new bundles and run bundle install:

gem 'haml'
gem 'figaro'
gem 'omniauth-google-oauth2'

2. Create a new controller for sessions, and a new database model for users:

rails generate session_migration
rails generate controller sessions
rails generate model User provider:string uid:string name:string refresh_token:string access_token:string expires:timestamp
rake db:migrate

3. Configure the session to use a database rather than cookies which have a 4KB limit:

# config/initializers/session_store.rb

Example::Application.config.session_store :active_record_store

4. Create your SessionsController:

# /app/controllers/sessions_controller.rb

class SessionsController < ApplicationController
  def create
    auth = request.env["omniauth.auth"]
    user = User.where(:provider => auth["provider"], :uid => auth["uid"]).first_or_initialize(
      :refresh_token => auth["credentials"]["refresh_token"],
      :access_token => auth["credentials"]["token"],
      :expires => auth["credentials"]["expires_at"],
      :name => auth["info"]["name"],
    url = session[:return_to] || root_path
    session[:return_to] = nil
    url = root_path if url.eql?('/logout')

    if user.save
      session[:user_id] = user.id
      notice = "Signed in!"
      logger.debug "URL to redirect to: #{url}"
      redirect_to url, :notice => notice
      raise "Failed to login"

  def destroy
    session[:user_id] = nil
    redirect_to root_url, :notice => "Signed out!"

5. Login to your Google Developers Console, create a new Project, and visit APIs & Auth:

6. Edit config/application.yml with these Google keys (figaro will make all of these settings available through ENV[property]):

# config/application.yml


7. Enable Omniauth to use Googleauth2 as a provider (approval_prompt must be an empty string otherwise it will force a prompt on every login):

# /config/initializers/omniauth.rb

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2,
    {name: "google_login", approval_prompt: ''}

8. Enable new routes:

# /config/routes.rb

Example::Application.routes.draw do
  # ...
  get "/auth/google_login/callback" => "sessions#create"
  get "/signout" => "sessions#destroy", :as => :signout

9. Now finally, you can add login/logout links in your navigation template, or whatever:

/ /app/views/home/index.html.haml

  - if current_user
    = link_to "Sign out", signout_path
    = current_user.name
    = current_user.inspect
  - else
    = link_to "Sign in with Google", "/auth/google_login"

10. Which uses a helper method, current_user, which loads the User model based on the session user_id:

# /app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  # ...
  helper_method :current_user


  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
Jevon Wright