How to authorize the google-api-ruby-client?
Asked Answered
A

2

7

I'm working to get the google-api-ruby-client gem working following the basic usage example here: Basic usage

require 'google/apis/drive_v2'

Drive = Google::Apis::DriveV2 # Alias the module
drive = Drive::DriveService.new
drive.authorization = ... # See Googleauth or Signet libraries

# Search for files in Drive (first page only)
files = drive.list_files(q: "title contains 'finances'")
files.items.each do |file|
  puts file.title
end

Where I'm stuck is drive.authorization. I have an authorized token already for the user via the gem omniauth-google-oauth2. How do I use that token with google-api-ruby-client?

Aruspex answered 29/6, 2016 at 22:35 Comment(0)
L
5

I too was stuck. IMO Google should have more elaborated in their documents, especially since all we had to do was just adding one request header...

Anyway, here is one example.

#
# Note I don't think we always have to define a class with such a conflict-prone name. 
# An anonymous class defined before every single API call should be also fine.
#
module Google
  class AccessToken
    attr_reader :token
    def initialize(token)
      @token = token
    end

    def apply!(headers)
      headers['Authorization'] = "Bearer #{@token}"
    end
  end
end
Drive = Google::Apis::DriveV2
drive = Drive::DriveService.new
drive.authorization = Google::AccessToken.new your_token

Reference: https://github.com/google/google-api-ruby-client/issues/296

Libretto answered 11/6, 2018 at 8:4 Comment(1)
And would I put this module in the helper folder? I suppose Rails magic will allow for use of these module anywhere?Dismissive
H
1

Similarly to other answers I followed this approach, where the model storing the auth and refresh tokens is used, abstracting API interactions from that logic.

# Manages access tokens for users when using Google APIs
#
# Usage:
# require 'google/apis/gmail_v1'
# Gmail = Google::Apis::GmailV1 # Alias the module
# service = Gmail::GmailService.new
# service.authorization = GoogleOauth2Authorization.new user
# service.list_user_messages(user.email)
#
# See also:
# https://github.com/google/google-api-ruby-client/issues/296
class GoogleOauth2Authorization
  attr_reader :user

  def initialize(user)
    @user = user
  end

  def apply!(headers)
    headers['Authorization'] = "Bearer #{token}"
  end

  def token
    refresh! if user.provider_token_expires_at.past?
    user.provider_access_token
  end

  private

  def refresh!
    new_token = oauth_access_token(
      user.provider_access_token,
      user.provider_refresh_token
    ).refresh!
    if new_token.present?
      user.update(
        provider_access_token: new_token.token,
        provider_token_expires_at: Time.zone.at(new_token.expires_at),
        provider_refresh_token: new_token.refresh_token
      )
    end
    user
  end

  def oauth_access_token(access_token, refresh_token)
    OAuth2::AccessToken.new(
      oauth_strategy.client,
      access_token,
      refresh_token: refresh_token
    )
  end

  def oauth_strategy
    OmniAuth::Strategies::GoogleOauth2.new(
      nil,
      Rails.application.credentials.oauth[:google_id],
      Rails.application.credentials.oauth[:google_secret]
    )
  end
end
Hollah answered 26/6, 2018 at 11:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.