Oauth2 has become the defacto standard for online authentication: Twitter, Facebook, Four Square, Amazon are some of the big players that rely on it for their APIs.
The Oauth authentication process requires an authentication server application where users login, and a client application that uses the server application for user authentication.
We’re going to create both the client and server application from scratch with rails using devise, doorkeeper and omniauth-oauth2 gems to speed up the process, make them work together and analyze how the authentication works.
In this first post we’re going to build the server application step by step.
The server application
Devise will provide authentication, while doorkeeper will allow the app to work as an Oauth2 server. Let’s generate a new app:
rails new oauth-server
then add devise and doorkeeper gems to the Gemfile:
gem "devise"
gem "doorkeeper"
generate the gems boilerplate and migrate the db:
rails g devise:install
rails g devise User
rails g doorkeeper:install
rails generate doorkeeper:migration
rake db:migrate
A bunch of files are generated in the process, among them there’s the config/initializers/doorkeeper.rb initializer. Let’s open this file and modify it to allow doorkeeper to use devise for authentication. Change the settings on the top of it as follows, remembering to comment out the “fail” instruction:
resource_owner_authenticator do
current_user || begin
session[:user_return_to] = request.fullpath
redirect_to new_user_session_url
end
end
admin_authenticator do
current_user || redirect_to(new_user_session_url)
end
The resource_owner_authenticator
block allows devise authenticated users to access their resources via doorkeeper. If the user is not authenticated we store the url where he came from in the session, and we redirect him to the login page.
The admin_authenticator
bock limits the access to the doorkeeper admin area only to registered users. This admin area is used to manage (create, update, destroy) the client application tokens required for the Oauth authentication.
You may want to limit the access to restricted group of user, for example to admins. This code may work for you:
admin_authenticator do
current_user && current_user.admin? || redirect_to(new_user_session_url)
end
Then let’s create a dummy user that we’ll use for experimenting in db/seed.rb:
User.create! email: 'test@test.com', password: 'password', password_confirmation: 'password'
rake db:seed
Let’s create the actual action that will provide the client app with the authenticated user information. We could build a separate controller, but let’s use application controller for the sake of brevity:
class ApplicationController < ActionController::Base
before_action :doorkeeper_authorize!, only: :me
def me
render json: User.find(doorkeeper_token.resource_owner_id).as_json
end
end
and update the routes as well:
Rails.application.routes.draw do
use_doorkeeper
devise_for :users
get '/me' => 'application#me'
end
The directive before_action :doorkeeper_authorize!, only: :me
applies only to the me
action, and it basically looks for a doorkeeper_token
, an object built starting from the oauth authorization code, if not found it will render with a 401 Unauthorized
header. The same token object is then used in the me
action body to retrieve the user details, which will be rendered as JSON.
Now we need to define root_path
as Devise requires (please read the gem readme), then we can start the server and see what happens if we try to access the /me
page:
rails s
curl -I localhost:3000/me
HTTP/1.1 401 Unauthorized
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Cache-Control: no-store
Pragma: no-cache
WWW-Authenticate: Bearer realm="Doorkeeper", error="invalid_token", error_description="The access token is invalid"
Content-Type: text/html
X-Request-Id: 109af7db-5c09-4175-b6f3-cbd902f4caff
X-Runtime: 0.003485
Server: WEBrick/1.3.1 (Ruby/2.1.0/2013-12-25)
Date: Fri, 30 Jan 2015 10:33:46 GMT
Content-Length: 0
Connection: Keep-Alive
Set-Cookie: request_method=HEAD; path=/
As you can see, since we’re not authenticated and we didn’t provide a valid token the application responds with a 401 Unauthorized
header.
Ideally the the client application will come to this url and get the user information, if authorized, and so the login process on the client app can complete.
So,everything is set for authentication, codewise, on the server application. The client application will need to be registered on the oauth-server app in order to be able to authenticate users. Let’s go and register it, heading your browser to http://localhost:3000/oauth/applications/new.
You will be redirected to the authentication page, fill in the form with the dummy user credentials in order to login (test@test.com, password) and you will be now presented a new form to create the new Oauth client application settings. Fill the form giving the name you prefer (I chose oauth-client) to the app and use this url as the redirect URI: http://localhost:3001/doorkeeper/callback
.
This url must follow omniauth (used on the client app) conventions, where doorkeeper stands for the authentication strategy name (we’re going to build it later, the name could be anything meaningful for us) and callback is a path fixture for omniauth recognition. We will start the client app on localhost:3001, of course, and please consider switching to the more secure https protocol when you are production ready.
After pressing submit you will be presented with a success page showing the client app authentication settings, which include the application id, the secret key and the callback url. we’re going to use them later, so take a note.

Now let’s create the actual action that will provide the client app with the authenticated user information. We should build a separated controller, but let’s use application controller for brevity:
class ApplicationController < ActionController::Base
before_action :doorkeeper_authorize!, only: :me
def me
render json: User.find(doorkeeper_token.resource_owner_id).as_json
end
end
The line before_action :doorkeeper_authorize!, only: :me
applies only to the me
action, and it basically looks for a doorkeeper_token
, an object built on the oauth authorization code, if not found it will render with a 401 Unauthorized
header. The same token object is then used in the me
action to retrieve the user information, which will be rendered in json format. Ideally the client application will come to this url and get the user information, if authorized, and so the login process on the client app can complete.
Let’s update the routes as well:
Rails.application.routes.draw do
use_doorkeeper
devise_for :users
get '/me' => 'application#me'
end
The server application is now ready. Next time we will build the client application that will fetch the user data from the server. See you soon!
You have to define root_path as Devise required:
After signing in a user, confirming the account or updating the password, Devise will look for a scoped root path to redirect to. For instance, when using a :user resource, the user_root_path will be used if it exists; otherwise, the default root_path will be used. This means that you need to set the root inside your routes:
root to: ‘home#index’
If not, navigating to http://localhost:3000/oauth/applications/new fails.
Thanks for clarifying that part, it was actually missing from the article.