anchorWhy another Authentication Engine?
Of course there are lots of authentication libraries for Rails already. While all of them are great and work well especially with traditional server rendered applications none of them are really lightweight and simple. In fact they are all pretty massive - all of them provide a lot more functionality than rails_api_auth does of course though. However, when you’re building an API and all you want is to provide a mechanism for users to exchange their login credentials for a token and then validate that incoming requests include a valid token in the Authorization
header, you just don’t need most of that functionality and could use sth. much smaller, easier to understand and debug. In fact, rails_api_auth is basically just the controller and model plus a few helper methods that we use in most of our Rails-based API projects. When we realized we were reimplementing those in most projects we decided to extract them into an engine so they could be easily reused and also shared with others.
anchorThe "Resource Owner Password Credentials Grant"
The "Resource Owner Password Credentials Grant" flow is really just a formalization of the process where the users send their login credentials to the server and in return receive a token (we’re using random Bearer tokens for now but will also support JSON Web Tokens (JWTs) soon). That token will then be sent in the Authorization
header in subsequent requests so that the server can validate the user’s identity. The engine stores these credentials and tokens in Login
models. Storing that data in a separate model instead of the application’s User
model keeps the authentication code clearly separated from user profile data etc. and makes the engine easier to integrate. The Login
model can be associated to the application’s User
model by setting the user_model_relation
configuration value (see the README for more info on configuring the engine).
The "Resource Owner Password Credentials Grant" flow defines 2 endpoints - one for obtaining a token and one for revoking it (the 2nd one is actually optional as users can be logged without any server interaction by simply deleting the token on the client):
token POST /token oauth2#create
revoke POST /revoke oauth2#destroy
Both of these endpoints are already implemented in the engine. To validate that incoming requests include a valid Bearer token, the library defines the authenticate!
method that is easily added as a before_action
in authenticated-only controllers:
class SecretThingsController < ApplicationController
include RailsApiAuth::Authentication
before_filter :authenticate!
end
When a valid token is present and a Login
with that token exists, the method will save that in the current_login
attribute so that it can be used in the controller. If no token is present or no Login
exists for the token, it will respond with 401 and prevent the actual controller action from being executed. The authenticate!
method can also be called with a block to add custom checks for the user’s authentication state.
anchorFacebook Authentication
Another common way of authenticating users that we’re using in many projects is Facebook authentication. The typical flow for this authentication type in web applications is opening a popup that displays Facebook’s login page and - after that - a page where the users grants your application access to their profile data. Once the user did that, Facebook will redirect to the web app and include an auth_code
in the response that the web app then takes and sends to its API to validate it and exchange it for a Bearer token.
rails_api_auth implements the API part of that in the POST /token
route as well - see the demo project for an example of how to use it.
anchorFeedback and contributions welcome!
As rails_api_auth is quite new and not yet widely used we’re happy to get feedback and suggestions for things we have missed. Also please try the gem and report bugs as you encounter them. Contributions and pull requests are also appreciated of course!