Harold Rangel Charris
Harold Rangel Charris

Reputation: 41

How can I connect garb with a token from omniauth_google_oauth2?

I need to connect to Google Analytics. I'm using omniauth_google_oauth2 for authenticating the user with the app, and this gives me a token. The problem is that I need to connect to this user's Google Analytics account. To connect GA to my app I'm using the garb gem which has only two methods for authentication; username/password, and OAuth token. When I use the token provided by omniauth_google_oauth2, it doesn't work.

How do I create this new token using only the oauth_token that I get from the authentication with omniauth_google_oauth2?

Upvotes: 4

Views: 1141

Answers (2)

topher
topher

Reputation: 301

I know I'm late to the party on this one but I solved a similar issue. You can't use omniauth_google_oauth2 with garb unless you use a fork of garb that supports oauth2. There is one here that is well maintained by Sija. However, you will need to use an oauth2 client object in order to create a session with this fork. You can get your user's profile set up using omniauth_google_oauth2 and make sure you save the refresh token for the user, then when you want to grab analytics data with garb, refresh the token with oauth2 and then pass that object into your garb session to pull the user's data. Here's an example after you have the refresh_token from omniauth stored somewhere:

client = OAuth2::Client.new YOURGOOGLEAPIKEY, YOURGOOGLEAPISECRET,
                                {
                                  :site => 'https://accounts.google.com',
                                  :authorize_url => "/o/oauth2/auth",
                                  :token_url => "/o/oauth2/token",
                                }
response = OAuth2::AccessToken.from_hash(client, :refresh_token => omniauth_refresh_token).refresh!
Garb::Session.access_token = response

Upvotes: 2

alexmuller
alexmuller

Reputation: 2237

I think the problem you're encountering is that garb will only authenticate a user using OAuth 1 (or a username/password combo), while omniauth_google_oauth2 is (obviously) OAuth 2.

The only solution I've found is to use Google's deprecated OAuth 1 implementation as follows...

Gemfile:

gem 'omniauth-google', :git => 'git://github.com/davidkpham/omniauth-google.git'
# This fork relaxes dependencies on omniauth itself

Initializer (for Google Analytics access):

provider :google, 'XXXXXXXXXXXX.apps.googleusercontent.com', 'YOUR_SECRET', scope: 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.google.com/analytics/feeds/'

On the callback, store some of the stuff passed back:

auth = request.env["omniauth.auth"]
session[:google_token] = auth.credentials.token
session[:google_secret] = auth.credentials.secret

Then construct an AccessToken for garb:

if session[:google_token] and session[:google_secret]
  consumer = OAuth::Consumer.new('XXXXXXXXXXXX.apps.googleusercontent.com', 'YOUR_SECRET', {
    :site => 'https://www.google.com',
    :request_token_path => '/accounts/OAuthGetRequestToken',
    :access_token_path => '/accounts/OAuthGetAccessToken',
    :authorize_path => '/accounts/OAuthAuthorizeToken'
  })
  garbsession = Garb::Session.new
  garbsession.access_token = OAuth::AccessToken.new(consumer, session[:google_token], session[:google_secret])
  # Once we have an OAuth::AccessToken constructed, do fun stuff with it
  ga_id = "UA-XXXXXXX-X"
  profile = Garb::Management::Profile.all(garbsession).detect {|p| p.web_property_id == ga_id}
  ga_monthly = GoogleAnalyticsDate.results(profile, :start_date => (Date.today - 30), :end_date => Date.today, :sort => :date)
  puts ga_monthly
end

Upvotes: 1

Related Questions