API key authentication with Rails

I recently completed a code challenge where part of the challenge was to build an API that authenticated a request via an API key. I’ll go over the basics of implementing this in this blog post.

Even if I’m working on an API specific Rails project, I prefer to namespace my Rails apps with “/api”. This gives me the flexibility to build full web applications on top of the same codebase in the future using the top level namespace if I wanted to. Also, it just feels “right”.

Let’s say that we’re going to be building an API that returns user data. Let’s assume that in our codebase, the database and the ActiveRecord model are already there and that the users table contains a column called api_key. In order to use the API, the client needs to pass a valid api_key in the header.

So, let’s start by namespacing our API in config/routes.rb. I’m also going to version the API in this, but this is up to you and what the requirements call for.

Here, you can see that I’m namespacing the API and setting the default format of all requests into the endpoints under the api namespace into json. This ensures that only json requests are accepted in all the controllers under the namespace api.

Whenever I’m creating a group of controllers under a new namespace, I like to create a new top-level controller. To do this, create a new folder named “api” directly under your “controllers” folder and create a new controller called ApiController. The new controller will look like this.

And just for clarification, we’ll be inhering all controller under the namespace “api” from this new Api::ApiController. For example, if we have a UsersController under the namespace “api”, it’ll look like this. Notice that this UsersController is under the namespace /api/v1/.

The authentication via an api_key part is in ApiController so let’s go through the code in the ApiController one by one.

In our ApiController, we have a protected method called authenticate that is called on each api request via before_callback method. In this method, we are taking in the api key that is passed via a header key called “X-Api-Key”. We use that api_key to query our database to see if a user with that api key exists. If that user exists, we store the instance of that user in the instance variable @user. Then if that @user variable is valid, we allow the api request to go through and if it isn’t valid, we return a an unauthorized http status code and break out from the code.

I found this to be a good and simple way to implement api authentication via api keys in Ruby on Rails. It gives a good base to build more advanced features like tracking how many api requests are being made per API key and then limiting (or throttling) them if needed.