Rails 3.1 OAuth Provider "invalid_grant" with devise_oauth2_providable
I am trying to set an oauth2 provider up using up on an application which has omniauth and devise already. The user.rb is now:
class User开发者_开发问答 < ActiveRecord::Base
has_many :authentications
has_many :graphs
devise :database_authenticatable,
:registerable,
:recoverable,
:rememberable,
:trackable,
:validatable,
:omniauthable,
:token_authenticatable,
:oauth2_providable,
:oauth2_password_grantable,
:oauth2_refresh_token_grantable,
:oauth2_authorization_code_grantable
.......
}
Everything else is implemented as expected, but I am getting the following error when I run this all locally and try to use the oauth2 gem (0.5.0) to connect to my client.
I end up on:
http://localhost:8080/oauth/callback?code=2ebd3d9d149b22becec37da7a8f1eb0d
which raises the exception:
e.to_yaml
"--- !ruby/exception:OAuth2::Error\nresponse: &70266332040280 !ruby/object:OAuth2::Response\n response: &70266332040340 !ruby/object:Faraday::Response\n env:\n :method: :post\n :body: ! '{\"error\":\"invalid_grant\",\"error_description\":\"invalid authorization\n code request\"}'\n :url: !ruby/object:Addressable::URI\n validation_deferred: false\n scheme: http\n normalized_scheme: !!null \n uri_string: !!null \n hash: !!null \n host: localhost\n authority: !!null \n normalized_host: !!null \n port: 3000\n normalized_port: !!null \n path: /oauth2/token\n normalized_path: !!null \n query: !!null \n normalized_query: !!null \n :request_headers:\n Content-Type: application/x-www-form-urlencoded\n :parallel_manager: !!null \n :request:\n :proxy: !!null \n :ssl: {}\n :status: 400\n :response_headers:\n content-type: application/json\n x-ua-compatible: IE=Edge\n cache-control: no-cache\n x-runtime: '0.119701'\n content-length: '82'\n server: WEBrick/1.3.1 (Ruby/1.9.2/2011-02-18)\n date: Wed, 05 Oct 2011 14:40:10 GMT\n connection: close\n :response: *70266332040340\n on_complete_callbacks: []\n options:\n :parse: !!null \n error: !ruby/exception:OAuth2::Error\n response: *70266332040280\n code: invalid_grant\n description: invalid authorization code request\n parsed:\n error: invalid_grant\n error_description: invalid authorization code request\ncode: invalid_grant\ndescription: invalid authorization code request\n"
I am also noticing that no state is provided, which in the latest draft (http://tools.ietf.org/html/draft-ietf-oauth-v2-22) is required for a callback. Could this be an issue?
As for output I am not getting any obvious errors in the server output:
http://pastie.org/2644028
Now, another thing worth noting is that I see a few SELECT's happening but I never see any data being inserted into the various tables, especially not to authorization_codes which happens just before this exception is thrown.
After looking at the queries, it looks like the current time is past the expired_at value. Below is the devise_oauth2_providable code that calls this error:
module Devise
module Strategies
class Oauth2AuthorizationCodeGrantTypeStrategy < Oauth2GrantTypeStrategy
def grant_type
'authorization_code'
end
def authenticate!
if client && code = AuthorizationCode.valid.find_by_token(params[:code])
success! code.user
elsif !halted?
oauth_error! :invalid_grant, 'invalid authorization code request'
end
end
end
end
end
That valid scope checks to see if the current time is greater than or equal to AuthorizationCode's expires_at field.
I'm no Rails genius but I do know my way around GitHub and I managed to find a few people making commits to their forks. By combining a few valid looking fixes into one location I managed to create a fork that worked fine for me:
https://github.com/socialcast/devise_oauth2_providable/pull/17
I set that as my source in Gemfile and now the callback works fine!
Now, I just need to work out how to stop access tokens expiring, or inject user_id into the darn response somehow... Work work work.
精彩评论