OAuth

Sometimes you want integrate your Ruby on Rails application with third-part services, but today almost all services use OAuth to improve security, mainly Google Services (at this example, Google Analytics).

Basically, the protocol defines an exchange of access tokens. If you wanna know more, I recommend the explanation of OAuth at Wikipedia, the OAuth reference by Google and the article “Using OAuth with the Google Data APIs”.

Let’s go straight to the code and implementation.

First of all, you need the OAuth gem at your application:

1
2
3
# Gemfile
...
gem 'oauth'

After this, you need declare your OAuth Service Credentials.
Google has “anonymous” keys to test, but to put your app in production, you should get real keys at Google’s Domain Management Page.
We declare our keys at config/environments files because we use different keys according the environment. So, at test.rb and development.rb we declare:

1
2
3
4
5
6
7
8
# config/environments/development.rb
...
OAUTH_CREDENTIALS={
  :google => {
    :key => "anonymous",
    :secret => "anonymous"
  }
}

but staging.rb and production.rb use real keys that are related to the domain of application.

After this, we create the model GoogleOAuth that retrieves OAuth Consumer entity that will access Google Data from APIs:

1
2
3
4
5
6
7
8
9
10
11
12
# app/models/google_oauth.rb
class GoogleOAuth

  def self.consumer
    OAuth::Consumer.new(OAUTH_CREDENTIALS[:google][:key], OAUTH_CREDENTIALS[:google][:secret], {
      :site => 'https://www.google.com',
      :request_token_path => '/accounts/OAuthGetRequestToken',
      :access_token_path => '/accounts/OAuthGetAccessToken',
      :authorize_path => '/accounts/OAuthAuthorizeToken'
    })
  end
end

After, we will create the controller to manipulate the communication with Google OAuth Authentication Service.
First, we need to redirect the user to Google Analytics authorization page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# app/controllers/oauth_authorization_controller.rb
class OAuthAuthorizationController < ApplicationController

  def index
    callback_url = url_for(:controller => "oauth_authorization", :action => "callback")
    begin
      @request_token = GoogleOAuth.consumer.get_request_token({:oauth_callback => callback_url}, {:scope => 'https://www.google.com/analytics/feeds'})
      if @request_token
        session[:request_token] = @request_token
        redirect_to @request_token.authorize_url
      else
        flash[:error] = "Unable to contact Google. Try again."
        redirect_to root_path
      end
    rescue => e
      flash[:error] = "Unable to contact Google. Try again."
      redirect_to root_path
    end
  end
end

When accessing this action of the controller, the user will be redirected to a Google page to login if the user wasn’t logged, and then, grant access of application to the service (at this example, Google Analytics).
Google OAuth user granting access to Google Analytics

But, to complete the cycle of authentication, your application needs a callback to Google that retrieves the access token. So, you need another action at your controller:

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
# app/controllers/oauth_authorization_controller.rb
class OAuthAuthorizationController < ApplicationController

  def index
    ...
  end

  def callback
    @request_token = session[:request_token]

    if @request_token.try(:secret)
      begin
        access_token = @request_token.get_access_token( {:oauth_verifier => params[:oauth_verifier]} )
        if access_token
          current_loggedin_user.update_attributes( :ga_access_token => access_token.token, :ga_access_secret => access_token.secret )
          flash[:notice] = "Application successfully connected with Google Analytics user account."
        end
      rescue => e
        flash[:error] = "Unable to connect with user account. Try again granting access to Google Analytics. (400)"
        redirect_to root_path
      end
    else
      flash[:error] = "Oops! Unable to connect with user account. Please, try again."
      redirect_to root_path
    end
  end
end
1
2
3
4
5
# config/routes.rb
...
  get "/connect_ga", :to => "oauth_authorization#index", :as => :ga_oauth
  get "/ga_callback", :to => "oauth_authorization#callback"
...

And it’s done!
Now, you can make requests do Google Analytics using OAuth and the access_token and access_secret tokens.
Here, an example on getting GA profiles using Garb gem:

1
2
3
   session = Garb::Session.new
   session.access_token = OAuth::AccessToken.new(GoogleOAuth.consumer, current_loggedin_user.access_token, current_loggedin_user.access_secret)
   Garb::Management::Profile.all(session)

So, what do you think? Sounds complicated? But it’s not!
Try it ;)

Here is another very helpful article : Google Analytics Integration with OAuth

Doubts? We are here to help!
Send us a message.