Example: Cracking Google OAuth With Ruby

2 Feb

I’ve been working on a project involving Google Contacts for the past few days, and found it extremely difficult and confusing to go through the Google Auth process. It’s probably because I’m still really new to interacting with other APIs and figuring out how the process works. I ended up getting a developer friend to help me, and it was great hearing his explanation of the entire REST API process, which I’m still wrapping my head around. Anyway, in case you’re building an application using the Google API, here is how the Google Auth process works with Ruby…

You can also view this example on github.

require 'typhoeus'
require 'json'
require 'google/api_client'

#register your project with google at https://code.google.com/apis/console/, get the below constants
REDIRECT_URI = 'http://YOUR_SITE/googleauth'

#first we send users to this URL:
google_contacts_api_uri = 'https://www.google.com/m8/feeds'
google_calendar_api_uri = 'http://www.google.com/calendar/feeds/default/allcalendars/full'

send_user_to = "https://accounts.google.com/o/oauth2/auth?scope=#{google_contacts_api_uri}+#{google_calendar_api_uri}&response_type=code&redirect_uri=#{REDIRECT_URI}&approval_prompt=force&client_id=#{CLIENT_ID}&hl=en-US&from_login=1&access_type=offline"

#the user approves the request and you get a code in your redirect URI 'http://YOUR_SITE/googleauth?code=YOUR_CODE
@code = 'YOUR_CODE' #=> get YOUR_CODE at the end of your redirect URI 'http://YOUR_SITE/googleauth?code=YOUR_CODE

#create a new Auth session
Auth.new({:code => @code})

#trade in your code for an access token, which expires in 1 hour, and a refresh token - to get a new access token when you need it
class Auth
  attr_reader :refresh_token , :access_token , :code , :token_expires_time

  def initialize args = {}
    args.each do |k,v|
    	instance_variable_set("@#{k}",v) unless v.nil?
    	acquire_tokens_with_code v if k == :code
    acquire_new_access_token unless @refresh_token.nil? #if we don't have a code, make sure we have the latest access_token

  #you trade in the code for an access token, which lasts only 1 hour, and a refresh token.
  #acquire_tokens_with_code (returns refresh & access token)
  def acquire_tokens_with_code code
    res = Typhoeus::Request.post('https://accounts.google.com/o/oauth2/token ', :params => {
      'code' => @code,
      'client_id' => CLIENT_ID,
      'client_secret' => CLIENT_SECRET,
      'redirect_uri' => REDIRECT_URI,
      'grant_type' => 'authorization_code'
    results = JSON.parse(res.body)
    @access_token = results['access_token']
    @refresh_token = results['refresh_token']
    @token_expires_time = results['expires_in'].to_i + Time.now.to_i

  #save the refresh token so you can get a new access token later on if you need to access the users data beyond the 1 hour access token limit
  def acquire_new_access_token
    res = Typhoeus::Request.post('https://accounts.google.com/o/oauth2/token ', :params => {
      'client_id' => CLIENT_ID,
      'client_secret' => CLIENT_SECRET,
      'refresh_token' => @refresh_token,
      'grant_type' => 'refresh_token'
    results = JSON.parse(res.body)
    @access_token = results['access_token']
    @token_expires_time = results['expires_in'].to_i + Time.now.to_i

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s