Skip to content
This repository

Client get_token method raises error incorrectly #75

Open
amnwebmaster opened this Issue · 9 comments

9 participants

amnwebmaster dexter Asa Wilson Yoshiyuki Sugimoto kyletns Per-Kristian Nordnes Najam az-azza Andrew Bondarets
amnwebmaster

Calling @client.auth_code.get_token(...) to Facebook gives an OAuth2::Error

Facebook correctly returns the access token but not as a hash but a string hence client.rb line 130 is incorrect

raise Error.new(response) unless response.parsed.is_a?(Hash) && response.parsed['access_token']

Should be:
raise Error.new(response) unless response.parsed['access_token']

dexter

I got the same issue

Asa Wilson

Also, having this issue.

Asa Wilson

You can add a parser with the code below. If you're using rails, a good spot to put it might be config/initializers/oauth2.rb. This assumes the body of the response will look something like this: "access_token=54626|345_435-534523DSF".

OAuth2::Response.register_parser(:text, 'text/plain') do |body|
  key, value = body.split('=')
  {key => value}
end

This will overwrite the existing :text parser. If that causes problems, you could change the parser to :facebook instead of :text and pass :parse => :facebook into the params of the get_token function when you call it, though I haven't tried that.

Yoshiyuki Sugimoto

Thanks, acvwilson. Your solution helped me.

kyletns

Thanks, acvwilson.

I ran into a problem because facebook actually returns a string with 2 keys, the token and the seconds until expiration.
So the string facebook returns looks more like:

access_token=abcdef_some_fb_code&expires=5000

Current Fb Docs here: http://developers.facebook.com/docs/authentication

So my token was being set to 'abcdef_some_fb_code&expires' with your fix. This minor tweak:

OAuth2::Response.register_parser(:text, 'text/plain') do |body|
  token_key, token_value, expiration_key, expiration_value = body.split(/[=&]/)
  {token_key => token_value, expiration_key => expiration_value}
end

Fixed it for me.

Per-Kristian Nordnes

I had the same kind of trouble, only my problem was:

1) I didn't use HTTPS to talk to the OAuth 2 API on the provider server (resulting in an OAuth2::Error in lib/omniauth/strategies/oauth2.rb:66)
2) The user hash on the server didn't respond with Content-type: application/json in the header (resulting in an oAuth2::Error in my strategy regarding access_token.get(userinfo_url) )

It was not the easiest stuff to debug, as the OAuth2:Error did not contain any extended info, and I had to raise them inside my strategy, overriding the OmniAuth::Strategies::OAuth2 methods.

On my wish list for the next release, is an easier way to debug these kind of problems when developing a custom strategy on the application side (the application which is using the strategy). Omniauth is "eating" the exception details, just showing a "invalid_credentials" error in that scope.

Najam

Same issue.. Fails to work with Github OAuth API..

require 'oauth2'

client = OAuth2::Client.new('< key >', '< secret >', :site => 'https://github.com/login/oauth/authorize')
auth_url = client.auth_code.authorize_url(:redirect_uri => 'https://github.com/login/oauth/access_token')
token = client.auth_code.get_token('authorization_code_value', :redirect_uri => 'https://github.com/login/oauth/access_token')
az-azza

The same goes for Yammer API. I noticed that in AccessToken initialization method access_token parameter is removed from hash and its content is cast to String and stored under token attribute...with yammer api it does contain a number of additional parameters and values like so:

"access_token": {
"view_subscriptions": true,
"expires_at": null,
....
"token": "xxxxxxxx",
}

so by casting to s it becomes just a blob of chars.

My quick workaround was a custom parser(based on previous comment) that adds custom parameter:

OAuth2::Response.register_parser(:ytext, 'text/plain') do |body|
parsed_body = JSON.parse(body)
parsed_body['raw_access_token'] = parsed_body['access_token']['token']
parsed_body
end

Andrew Bondarets

I've had same issue, just set parser type to solve this issue in your provider options if you have response body as json.

option :token_params, {:parse => :json}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.