开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜