Skip to content

Client Obtain Token

Nov Matake edited this page Feb 21, 2018 · 17 revisions

Pre Requirements

Initialize client first.

Basic Concept

OAuth 2.0 defines several flows to obtain access tokens. (For more details, please consult the RFC6749)

rack-oauth2 run each flow following

  1. set grant (the way to set grant is different in each flow)
  2. call client.access_token!

Code Flow

Code Flow would be the most basic flow to get an access token for server-side apps.

session[:state] = SecureRandom.hex(16)

# Authorization Request
authorization_uri = client.authorization_uri(
  scope: [:profile, :email],
  state: session[:state]
)
`open "#{authorization_uri}"`

# Authorization Response
puts "# Authorization Code"
code = gets.strip

# Token Request
client.authorization_code = code
client.access_token! # => Rack::OAuth2::AccessTokens subclass

rack-oauth2 uses Authorization header for Client Authentication as default.

If your OAuth Server doesn't support Basic Auth for Client Authentication and require including client_secret in request body, do

client.access_token! :body

If your OAuth Server requires JWT bearer client assertion (a.k.a. private_key_jwt) like iGov-complient IdPs, follow this gist. (You can replace OpenIDConnect with Rack::OAuth2 if you don't need ID Token & UserInfo API support) https://gist.github.com/nov/98d26044e2f7c5b7d8fdba2b9bd101b4

Implicit Flow

session[:state] = SecureRandom.hex(16)

# Authorization Request
authorization_uri = client.authorization_uri(
  scope: [:profile, :email],
  state: session[:state],
  response_type: :token
)
`open "#{authorization_uri}"`

You'll get access_token out side of ruby world.

Hybrid Flow

session[:state] = SecureRandom.hex(16)

# Authorization Request
authorization_uri = client.authorization_uri(
  scope: [:profile, :email],
  state: session[:state],
  response_type: [:code, :token]
)
`open "#{authorization_uri}"`

You'll get access_token out side of ruby world. After you get code, do same with code flow.

Client Credentials Flow (a.k.a 2-legged)

Client Credentials Flow doesn't require any user interaction.

More over, since you already set client_secret in client initialization, you don't need to set any grant here.

Just call client.access_token!.

client.access_token! # => Rack::OAuth2::AccessTokens subclass

Resource Owner Credentials Flow

In this flow, your client needs to obtain end-user's username & password directly.

The way to obtain them is up to you.

client.resource_owner_credentials = 'username', 'password'
client.access_token! # => Rack::OAuth2::AccessTokens subclass

Refresh Token Flow

client.refresh_token = '02e27f838b6e378eb1259...'
client.access_token! # => Rack::OAuth2::AccessTokens subclass