RailsApiAuth
Rails API Auth is a lightweight Rails Engine that implements the "Resource Owner Password Credentials Grant" OAuth 2.0 flow (RFC 6749) as well as Facebook and Google authentication for API projects.
It uses Bearer tokens (RFC 6750) to authorize requests coming in from clients.
Installation
To install the engine simply add to the application's Gemfile
gem 'rails_api_auth'
and run:
bundle install
Rails API Auth also adds a migration to the application so run
rake db:migrate
as well to migrate the database.
Usage
Rails API Auth stores a user's credentials as well as the tokens in a Login
model so that this data remains separated from the application's User
model
(or Account
or whatever the application chose to store profile data in).
After installing the engine you can add the relation from your user model to
the Login
model:
class User < ActiveRecord::Base
has_one :login # this could be has_many as well of course
end
When creating a new User
in the host application, make sure to create a
related Login
as well, e.g.:
class UsersController < ApplicationController
def create
user = User.new(user_params)
if user.save && user.create_login(login_params)
head 200
else
head 422 # you'd actually want to return validation errors here
end
end
private
def user_params
params.require(:user).permit(:first_name, :last_name)
end
def login_params
params.require(:user).permit(:identification, :password, :password_confirmation)
end
end
The engine adds 2 routes to the application that implement the endpoints for acquiring and revoking Bearer tokens:
token POST /token(.:format) oauth2#create
revoke POST /revoke(.:format) oauth2#destroy
These endpoints are fully implemented in the engine and will issue or revoke Bearer tokens.
In order to authorize incoming requests the engine provides the
authenticate!
helper that can be used in controllers to make sure the
request includes a valid Bearer token in the Authorization
header (e.g.
Authorization: Bearer d5086ac8457b9db02a13
):
class AuthenticatedController < ApplicationController
include RailsApiAuth::Authentication
before_action :authenticate!
def index
render json: { success: true }
end
end
If no valid Bearer token is provided the client will see a 401 response.
The engine also provides the current_login
helper method that will return the
Login
model authorized with the sent Bearer token.
You can also invoke authenticate!
with a block to perform additional checks
on the current login, e.g. making sure the login's associated account has a
certain role:
class AuthenticatedController < ApplicationController
include RailsApiAuth::Authentication
before_action :authenticate_admin!
def index
render json: { success: true }
end
private
def authenticate_admin!
authenticate! do
current_login.account.admin?
end
end
end
See the demo project for further details.
Configuration
The Engine can be configured by simply setting some attributes on its main module:
RailsApiAuth.tap do |raa|
raa.user_model_relation = :account # this will set up the belongs_to relation from the Login model to the Account model automatically (of course if your application uses a User model this would be :user)
# Facebook configurations
raa.facebook_app_id = '<your Facebook app id>'
raa.facebook_app_secret = '<your Facebook app secret>'
raa.facebook_redirect_uri = '<your Facebook app redirect uri>'
# Google configurations
raa.google_client_id = '<your Google client id>'
raa.google_client_secret = '<your Google client secret>'
raa.google_redirect_uri = '<your app redirect uri>'
# Edx configurations
raa.edx_client_id = '<your Edx client id>'
raa.edx_client_secret = '<your Edx client secret>'
raa.edx_domain = '<your Edx app domain>'
raa.edx_redirect_uri = 'your Edx app redirect uri'
# Force SSL for Oauth2Controller; defaults to `false` for the development environment, otherwise `true`
raa.force_ssl = false
end
A note on Edx Oauth2 code flows
It is nesescary to include the Edx username in the request when making a call rails_api_auth call /token. When rails_api_auth interfaces with Edx's user api, the username is need to retrieve user data, not just a valid oauth2 token.
E.g.
headers = {
username: "alice",
auth_code: "alices_authorization_code",
grant_type: "edx_auth_code"
}
Contribution
See CONTRIBUTING.
License
Rails API Auth is developed by and © simplabs GmbH and contributors. It is released under the MIT License.