Skip to content

Testing your provider with OAuth2 gem

sumirolabs edited this page Apr 3, 2020 · 11 revisions

Set up the client

To test your provider, first make sure you have installed the oauth2 gem.

Go to your provider and create a client for you. If you haven't set up a provider yet, you can download this provider example built with Devise.

You can fill in any redirect uri for now since we're not using a web app. For testing purposes, fill in with urn:ietf:wg:oauth:2.0:oob. This will tell doorkeeper to display the authorization code instead of redirecting to a client application (that you don't have now).

To setup the client, go to your terminal and fire up irb and type:

require 'oauth2'

client_id     = '...' # your client's id generated with rake db:setup
client_secret = '...' # your client's secret
redirect_uri  = '...' # your client's redirect uri
site          = "http://localhost:3000" # your provider server, mine is running on localhost

client = OAuth2::Client.new(client_id, client_secret, :site => site)

Now that your client is ready, you can request an authorization code.

Authorization Code

Grab the authorization url with:

client.auth_code.authorize_url(:redirect_uri => redirect_uri)
# => http://localhost:3000/oauth/authorize?response_type=code&client_id=...&redirect_uri=...

Go to this url in your browser. You'll see the authorization endpoint. If you click on Authorize, you'll see a page with the authorization code in it:

development-auth-code

NOTE: You'll see this if you fill in the redirect uri of your client with urn:ietf:wg:oauth:2.0:oob. If you used another URL, then you'll get redirected to it with the code parameter in the query.

With this code you will request the access token.

Access token

To request an access token, type:

code = "..." # code you got in the redirect uri
token = client.auth_code.get_token(code, :redirect_uri => redirect_uri)
# => <#OAuth2::AccessToken ...>

You now have access to the provider's API, if you have any. If you downloaded the provider example, you can get all profiles resources:

response = token.get('/api/v1/profiles.json')
JSON.parse(response.body)
# => [ { "username": "something", ... } ]

Congratulations! You just made your first request to the doorkeeper provider!

RSpec

For testing with RSpec you will need to point Faraday to the current running Rack (test) application.

@oauth = OAuth2::Client.new('client_id', 'client_secret') do |b|
  b.request :url_encoded
  b.adapter :rack, Rails.application
end

If your doorkeeper routes depend on the domain, you can also set the site option (defaults to http://www.example.org):

@oauth = OAuth2::Client.new('client_id', 'client_secret', site: 'https://login.example.org') do |b|
   [...]
end

Example using password credentials flow

The following example shows an authentication test for the Resource Owner Password Credentials flow (using steak):

require 'acceptance/acceptance_helper'

feature 'OAuth authorization' do
  let(:app) { create(:application) }
  let(:user) { create(:user) }

  scenario 'auth ok' do
    client = OAuth2::Client.new(app.uid, app.secret) do |b|
      b.request :url_encoded
      b.adapter :rack, Rails.application
    end
    token = client.password.get_token(user.email, user.password)
    token.should_not be_expired
  end

  scenario 'auth nok' do
    client = OAuth2::Client.new(app.uid, app.secret) do |b|
      b.request :url_encoded
      b.adapter :rack, Rails.application
    end
    lambda {client.password.get_token(user.email, "123")}.should raise_error(OAuth2::Error)
  end
end

To get this example above to work you'll also have to follow the Using Resource Owner Password Credentials flow.

Testing the Refresh token is also quite easy, just call #refresh! on the OAuth2 token:

require 'acceptance/acceptance_helper'

feature 'OAuth authorization' do
  let(:app) { create(:application) }
  let(:user) { create(:user) }

  scenario 'refresh ok' do
    client = OAuth2::Client.new(app.uid, app.secret) do |b|
      b.request :url_encoded
      b.adapter :rack, Rails.application
    end
    token = client.password.get_token(user.email, user.password)
    token.should_not be_expired

    Timecop.freeze(Time.now + 1.day) do
      expect(token).to be_expired

      token2 = token.refresh!
      expect(token2).not_to be_expired
    end
  end
end
Clone this wiki locally