99miles
99miles

Reputation: 11232

fetch_access_token! in Google API -- "Missing authorization code."

I'm using the Google API Ruby Client get get access to users' calendars.

I get access with:

  client_id: "xxxxx"
  client_secret: "xxxxx"
  access_type: "offline"
  approval_type: ""
  scope: "https://www.google.com/calendar/feeds/ https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/calendar"
  callback_path: "/app/oauth_response"

  provider :google_oauth2, GOOGLE_API['client_id'], GOOGLE_API['client_secret'], 
            { access_type: GOOGLE_API['access_type'], 
              approval_prompt: GOOGLE_API['approval_prompt'], 
              scope: GOOGLE_API['scope'], 
              callback_path: GOOGLE_API['callback_path'],
              path_prefix: GOOGLE_API['path_prefix']}

When the response comes back it has a refresh token, access token, expired_at, etc. I am then able to make API requests with the access code. But once that access code expires (after an hour), I believe I need to use the refresh token to get a new access token, correct?

Here's the call I'm making:

HTTParty.get('https://www.google.com/calendar/feeds/default/owncalendars/full', :query => {:alt => "jsonc", :access_token => access_token})

Which tells me that my token expired. So I try to get a new one. But when I try to do that I get this:

@client.authorization.fetch_access_token!
ArgumentError Exception: Missing authorization code.

I see that in my @client object, @code=nil. I'm assuming that's what needs to be set, but I don't get a 'code' property returned from my initial request.

How do I get that code, or if I don't need it, what am I doing wrong? Thanks!

Upvotes: 2

Views: 8484

Answers (3)

DonPaulie
DonPaulie

Reputation: 2234

In the client there is following code (https://github.com/google/signet/blob/621515ddeec1dfb6aef662cdfaca7ab30e90e5a1/lib/signet/oauth_2/client.rb#L935), so you need to remove aredirect_uri, when you do not want to get access token.

if self.redirect_uri
  # Grant type was intended to be `authorization_code` because of
  # the presence of the redirect URI.
  raise ArgumentError, 'Missing authorization code.'
end

Upvotes: 0

Steve Bazyl
Steve Bazyl

Reputation: 11702

Most likely the the refresh token isn't set in @client.authorization at the point you're calling fetch_access_token!

Take a look at https://github.com/google/signet/blob/master/lib/signet/oauth_2/client.rb

That error message only appears in the fall through for an unknown/unspecified grant_type. grant_type itself is inferred based on the state of the authorization client.

In your use case, trying to refresh a token, it should be 'refresh_token' and grant_type will return that value if a refresh_token is set. My hunch is if you dump the value of @client.authorization.refresh_token and @client.authorization.grant_type they'll both be nil.

The fix would be to just to make sure you properly restore the refresh_token prior to calling that method.

Upvotes: 3

Claudio Cherubino
Claudio Cherubino

Reputation: 15024

The Ruby client library takes care of automatically getting a new access token from the refresh token when the former expires, so you don't need to do anything to handle that case.

Upvotes: 0

Related Questions