OAuth2 Client Ruby
A Ruby wrapper based on the OAuth 2.0 specification for build oauth2 clients. It is designed with the philosophy that
many oauth2 providers implement OAuth 2.0 differently and not exactly according to the
RFC. With this gem, a developer has some degree of flexibilty in creating a
client that will work with different OAuth2 providers. This flexibilty comes at the same price of having to implement
a few things yourself. To that effect, an access token response is returned as an HTTPResponse from which the response
body can be extracted. It turns out that not every oauth2 providers returns tokens in the same format. Therefore, rather
than make assumptions about the token response, this gem leaves that responsiblity to the developer.
Bundled with the gem are working sample clients for Google, Yammer and Github. The structure of the clients is easy to
follow thus making it possible to simply copy code from one client and simply substitute the rights credentials and request
URL paths.
For more about the standard checkout: http://tools.ietf.org/html/rfc6749
Installation
gem install oauth2-client
Resources
Usage Examples
require 'oauth2'
@client = OAuth2Client::Client.new('https://example.com', 's6BhdRkqt3', '4hJZY88TCBB9q8IpkeualA2lZsUhOSclkkSKw3RXuE')
client.authorization_code.authorization_path(:redirect_uri => 'http://localhost/oauth2/cb')
Authorization Grants
The client wraps around the creation of any given grant and passing in the parameters defined in the configuration
file. The supported grants include Authorization Code, Implicit, Resource Owner Password Credentials, Client Credentials.
There is also support for device authentication as described in Google's OAuth 2.0 authentication methods(https://developers.google.com/accounts/docs/OAuth2ForDevices). They are available via the authorization_code
, implicit
, password
, client_credentials
, refresh_token
and device
methods on a client object.
The get_token
method on the grants does not make any assumptions about the format ofthe response from the OAuth provider. The ideal
case would be to treat all responses as JSON. However, some services may respond with in XML instead of JSON. The get_token
method
therefore, returns with an HTTPResponse object.
Authorization Code
auth_url = client.authorization_code.authorization_path(:redirect_uri => 'http://localhost/oauth2/cb')
token_url = client.authorization_code.token_path(
:code => aXW2c6bYz,
:redirect_uri => 'http://localhost/oauth2/cb')
Implicit Grant
auth_url = client.implicit.authorization_path(:redirect_uri => 'http://localhost/oauth2/cb')
Password Credentials
token = client.password.get_token('username', 'password')
Refresh Token
token = client.refresh_token.get_token(refresh_token_value, :params => {:scope => 'abc xyz', :state => 'state'})
Client Credentials
token = client.client_credentials.get_token
Device Code
auth_url = client.device_code.authorization_path(:scope => 'abc xyz', :state => 'state')
token = client.device_code.get_token(device_auth_code)
Using a custom Http wrapper
By default, oauth2-client uses a Net::HTTP
wrapper called OAuth2Client::HttpConnection
. However, if you wish to use a different HTTP library, you only
need to create a wrapper around your favorite library that will respond to the send_request
method.
class TyphoeusHttpConnection
def initialize(site_url, connection_options={})
@site_url = site_url
@connection_options = connection_options
end
def base_url(path)
@site_url + path
end
def send_request(http_method, request_path, options={})
params = options[:params] || {}
headers = options[:headers]|| {}
method = method.to_sym
client = Typhoeus
case method
when :get, :delete
when :post, :put
options[:body] = options.delete(:params) if options[:params]
else
raise UnhandledHTTPMethodError.new("Unsupported HTTP method, #{method}")
end
response = client.send(http_method, base_url(request_path), params)
end
end
oauth_client = OAuth2Client::Client.new('example.com', client_id, client_secret, {
:connection_client => TyphoeusHttpConnection,
:connection_options => {}
})
Client Examples
This library comes bundled with two sample implementations of Google and Yammer OAuth clients. These clients are
meant to showcase the degree of flexibilty that you get when using this library to interact with other OAuth 2.0
providers.
Google Client
google_client = GoogleClient.new('https://accounts.google.com', '827502413694.apps.googleusercontent.com','a2nQpcUm2Dgq1chWdAvbXGTk')
Client-side authorization URL(Implicit grant)
auth_url = google_client.webserver_authorization_url(
:scope => 'https://www.googleapis.com/auth/userinfo.email',
:state => '/profile',
:redirect_uri => 'https://oauth2-login-demo.appspot.com/code',
:approval_prompt => 'force')
Server-side authorization URL(Authorization code grant)
auth_url = google_client.clientside_authorization_url(
:scope => 'https://www.googleapis.com/auth/userinfo.email',
:state => '/profile',
:redirect_uri => 'http://localhost/oauth/code',
:approval_prompt => 'force')
response = google_client.exchange_auth_code_for_token(
:params => {
:code => '4/dbB0-UD1cvrQg2EuEFtRtHwPEmvR.IrScsjgB5M4VuJJVnL49Cc8QdUjRdAI',
:redirect_uri => 'http://localhost/oauth/token'
}
)
response.inspect
response.body
Github Client
gihub_client = GithubClient.new('https://github.com', '82f971d013e8d637a7e1', '1a1d59e1f8b8afa5f73e9dc9f17e25f7876e64ac')
Server-side authorization URL(Authorization code grant)
auth_url = gihub_client.webserver_authorization_url
response = gihub_client.exchange_auth_code_for_token({
:code => '11a0b0b64db56c30e2ef',
:redirect_uri => 'https://localhost/callback',
})
response.inspect
response.body
Supported Ruby Versions
This library aims to support and is tested against the following Ruby
version:
- Ruby 1.8.7
- Ruby 1.9.2
- Ruby 1.9.3
This library may inadvertently work (or seem to work) on other Ruby
implementations, however support will only be provided for the versions listed
above.
Copyright
Copyright (c) 2013 Kevin Mutyaba
See [LICENSE][license] for details.
[license]: https://github.com/tiabas/oauth2-client/blob/master/LICENSE