googleapis / google-api-ruby-client

REST client for Google APIs
Apache License 2.0
2.81k stars 872 forks source link

Discrepancy between example code here and Ruby Quickstart Guide for Drive API #279

Closed ShivanKaul closed 8 years ago

ShivanKaul commented 9 years ago

As starter code, on the README, we are told to use the Drive module thusly:

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

But in the Ruby Quickstart Guide for Drive API, the following code is used:

# Initialize the API
client = Google::APIClient.new(:application_name => APPLICATION_NAME)
client.authorization = authorize
drive_api = client.discovered_api('drive', 'v2')

I understand that the instructions in this README say to use '0.9.pre3' as opposed to the Quickstart guide. But then I was wondering: how would I do authorization? The version used by the Quickstart guide depends on Launchy for the authorization, but I think that dependency is removed in 0.9.pre3.

rusikf commented 9 years ago

@ShivanKaul Authorization with discovered_api method is old style api, just look migration guides Launchy is not needed on all authorization types. Read this guide too

sqrrrl commented 9 years ago

Yeah, not all the samples have been updated to the new API. Those will be updated soon, but as mentioned in the previous comment, use the migration guide in the mean time to translate the examples from the old API to the current one.

jeremyhaile commented 9 years ago

@rusikf @sqrrrl the migration guide does not detail how to upgrade authorization in the new version as detailed on this github issue: https://github.com/google/google-api-ruby-client/issues/291

We cannot figure out how to migrate our authorization from 0.8.x to 0.9.x

sqrrrl commented 9 years ago

@jeremyhaile - create the authorization object your self:

client.authorization = Signet::OAuth2::Client.new(
  :authorization_uri => 'https://accounts.google.com/o/oauth2/auth',
  :token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
  :client_id => '...',
  :client_secret => '...',
  :scope => '...',
  :redirect_uri => '...'
)

I'll add a note to the migration guide for how to create an signet client as well as adapt other oauth libraries (a few people asked about omniauth/devise, oauth2, etc.)

FWIW, there are some pending changes to google/google-auth-library-ruby aimed at making auth a lot simpler.

jeremyhaile commented 9 years ago

@sqrrrl Thanks - that works!

Is there a way to use "API key" authorization? For example, the equivalent of passing "?key=" to the API directly. We have some places where we are retrieving info using API keys, and I can't figure out how to get this working using the ruby client.

sqrrrl commented 9 years ago

@jeremyhaile Just set it at the client/service level

client.key = ...

While it's technically valid to set it on a per-request basis, given that in the vast majority of cases people are either using an API entirely with keys or entirely with access tokens, I limited it to the service level to keep the individual method signatures cleaner. That, and it's usually harmless to specify a key and a token together (auth token can be specified per method, unlike keys.) So just set it when you create the service/client and you're good to go

jeremyhaile commented 9 years ago

@sqrrrl Thanks - that worked. I did notice that if you don't have a token, you need to leave the authorization as nil to get it to just use the key. Otherwise you can get errors when making api calls using just a "key".

jeremyhaile commented 9 years ago

@sqrrrl It would be nice if there was a short example in the README of "Authorization using an API key" "Authorization using OAuth tokens" etc. One example of each would make this much easier to figure out!

sqrrrl commented 9 years ago

The key should be sent for all requests if it's configured, but yes, tokens take precedence over the API key on the back end.

Will update the README as suggested.

jeremyhaile commented 9 years ago

@sqrrrl Using the new API I've noticed that it does not appear to be automatically fetching a new access token using the refresh token if authorization fails. Has something changed in that respect or is there something I need to enable automatic refetching?

If I manually call client.authorization.fetch_access_token! it fetches a new token, but this used to be done automatically.

sqrrrl commented 9 years ago

@jeremyhaile Tokens should be getting refreshed. https://github.com/google/google-api-ruby-client/blob/master/spec/google/apis/core/http_command_spec.rb#L30

apply! is at https://github.com/google/google-auth-library-ruby/blob/master/lib/googleauth/signet.rb

It's possible that there is a small race condition. apply! is only refreshing if it thinks the token is expired based on the expiration time. It's possible the server thinks it is expired before the client does. If you can confirm if that is the case, it's easy enough to fix.

sqrrrl commented 9 years ago

FYI - added API key info to readme.

sqrrrl commented 8 years ago

Drive API (and a bunch of other related APIs) are now using the new style in their guides & snippets.