Google-api-ruby-client: Access google apis using access_token and refresh_token

Created on 11 Oct 2015  路  7Comments  路  Source: googleapis/google-api-ruby-client

Given that a user authenticated my application and that I have the access and refresh token (as strings)...

how can I use those tokens with this gem to access different google apis already added to the scopes before ?

triage me

Most helpful comment

for future reference here is a full example

class AccessToken
  attr_reader :token
  def initialize(token)
    @token = token
  end

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

access_token = AccessToken.new 'SECRET_TOKEN'
drive = Google::Apis::DriveV2::DriveService.new
drive.authentication = access_token
drive.list_files # works ( If you get unauthorized error ... refresh the access token )

All 7 comments

You can create an instance of Signet::OAuth2::Client with the access token and supply that and the credentials. The client knows how to work with signet.

The only real requirement for credentials is that is has to be an object that responds to apply! and takes a hash of HTTP headers as it's parameter and updates the authorization header. For example, you could just write a simple adapter like:

class AccessToken
  attr_reader :token
  def initialize(token)
    @token = token
  end

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

Likewise, if you're using a different gem like oauth2 you just need to mix in the apply! method to update the header hash...

In any case, the readme contains some details about how to actually pass the credentials in to the client.

for future reference here is a full example

class AccessToken
  attr_reader :token
  def initialize(token)
    @token = token
  end

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

access_token = AccessToken.new 'SECRET_TOKEN'
drive = Google::Apis::DriveV2::DriveService.new
drive.authentication = access_token
drive.list_files # works ( If you get unauthorized error ... refresh the access token )

It should be authorization not authentication.

access_token = AccessToken.new 'SECRET_TOKEN'
drive = Google::Apis::DriveV2::DriveService.new
drive.authentication = access_token
drive.list_files # works ( If you get unauthorized error ... refresh the access token )

Hey i tried the above @gregorym and still get "unauthorized error" any clues?

@pitops I get the same response:

Error - #<Google::Apis::AuthorizationError: Unauthorized>

How'd you go about solving this?

require 'google/apis/sheets_v4'
require 'google/apis/drive_v2'
require 'googleauth'

class GoogleService
  attr_accessor :sheets, :drive

  def initialize(user)
    auth = Signet::OAuth2::Client.new(
      token_credential_uri: 'https://oauth2.googleapis.com/token',
      client_id: ENV["GOOGLE_CLIENT_ID"],
      client_secret: ENV["GOOGLE_CLIENT_SECRET"],
      refresh_token: user.refresh_token
    )
    auth.fetch_access_token!
    user.update(token: auth.access_token)


    sheets = Google::Apis::SheetsV4::SheetsService.new
    sheets.authorization = auth
    @sheets = sheets

    drive = Google::Apis::DriveV2::DriveService.new
    drive.authorization = auth
    @drive = drive
  end
end

Here's an example I'm using. I'm naively refreshing the token everytime instead of checking the expires timestamp.

I just use this to refresh:

    token_store = Google::Auth::Stores::FileTokenStore.new(:file => 'tokens.yaml')
    authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope, token_store, '/oauth2callback')

    user_id = put the correct user here!!!
    @credentials = authorizer.get_credentials(user_id, request)
    @credentials.refresh!
Was this page helpful?
0 / 5 - 0 ratings