DRY Your Rails APIs

Ever find your rails APIs getting large, unmanageable and very repetitive? Perhaps you're starting out a new rails API based application and want to make your life easy.

Ever find your rails APIs getting large, unmanageable and very repetitive? Perhaps you're starting out a new rails API based application and want to make your life easy.…

Read More

Secure your API Keys with JWT

A static, never-changing API key poses a security risk - it's essentially an obsfucated primary key - say for some sort of User. If this API key is ever leaked - for example, in a log file or you accidentally use HTTP - then anyone can act on behalf of you indefinetly until the API key is changed.

featured-image

JSON Web Tokens to the Rescue

We can use the JSON Web Token standard (make sure to read that link before you continue!) to create limited use API authorization tokens that last for a short period of time (for example, 2 seconds). This gives us plenty of time to make a complete HTTP request, yet causes any previous tokens to become useless.

Implementation

Say we have some sort of blog API service where a user can make blog posts using an API. With a traditional API key, you might have a User model with an api_key field.

Using JWT, you would have an api_secret field. Unlike the API key method, this secret is never sent between the client and the API.

To make this transaction successful, both the client and the API server need to know the following:

  • The User ID
  • Some shared secret

Client-Side

The client-side implementation might look something like this:

API Server

The API server might have an implementation that looks similar to this. Note some checks (such as checking for the presence of an Authorization header are ommited)

An Even More Secure Implementation

You can assign an unique one-time use jti field to your JWT payload. Using some redis magic, you can completely remove the possibility of a replay attack - meaning if your JWT token is compromised, it can never be used again.

Client-Side

This takes some inspiration from the Zendesk JWT implementation.

Server-Side

We can modify the set_current_user_from_jwt_token from earlier:

A static, never-changing API key poses a security risk - it's essentially an obsfucated primary key - say for some sort of User. If this API key is ever leaked - for example, in a log file or you accidentally use HTTP - then anyone can act on behalf of…

Read More

DRY up your JSON APIs with Rails

Making an API in rails can become very ugly if not done correctly. Odds are, your API requirements include something like the following:

  • Authentication
  • CRUD operations
  • Useful error messages

Authorization

Let's start with the easiest part: authorization.

We clearly see that the @user = User.find_by(api_key: request.authorization) is repeated twice. Let's move that into a before_action.

To follow best practices, we will make the following changes:

  1. Make an ApiController for other API controllers to inherit
  2. Set the @user object as current_user.

The ApiController will be the base for our future API controllers.

Finally, we can inherit from the ApiController and all of our actions will be protected:

Re-Usable Views

An easy way to render your models is to use the to_json method. However, it can prove to be painful if you wish to use only specific fields, especially if they're nested. For example:

The solution is to bring the V back into MVC for your APIs using a tool like jbuilder. Your controller method will look very light and simple:

And your view will look like this:

DRY up your CRUD with rescue_from

It may be tempting to follow the traditional flow of rails model saving:

By using the rescue_from method, you can significantly DRY up your code. Let's add to our ApiController:

Now the rest of your controllers can become incredibly DRY:

Better Error Messages with StrongParameters

For DRY and useful API error messages, you can also use StrongParameters to your advantage:

And now in your other controllers:

Now your end user will automatically be given a descriptive error message if they forget a parameter!

Making an API in rails can become very ugly if not done correctly. Odds are, your API requirements include something like the following: Authentication CRUD operations Useful error messages Authorization Let's start with the easiest part: authorization. We clearly see that the @user = User.find_by(api_key: request.authorization)…

Read More

HTTPFiesta

Ever find it ugly to validate httparty responses? Now there's a super simple way to validate your HTTP responses using the httpfiesta gem.

The gem allows you to validate any response using a single line of code in a very DRY manner:

response = HTTParty.get 'http://example.com'  
response.assert.status(200).content_type(:json)

Check out the GitHub repository repository for more information!

Ever find it ugly to validate httparty responses? Now there's a super simple way to validate your HTTP responses using the httpfiesta gem. The gem allows you to validate any response using a single line of code in a very DRY manner: response = HTTParty.get 'http://example.com' response.assert.…

Read More