🔐 Secure a Rails API with Auth0
Tags: rails, security, programming
Published: 2021-10-13 12:36:53

#### 📔 Learn how to secure an API written using Ruby On Rails with Auth0 authorization services.

### <br>

If you want to expose an API publicly on the Internet, authorization will be a requirement for you sooner or later. You want to verify that the client consuming the API has the appropriate permissions.

This guide is exactly about that. We'll be securing an API written using [Ruby On Rails](https://rubyonrails.org/), with [Auth0](https://auth0.com/) as the authorization server.

There's a repository with the code so that you can follow along in [Github](https://github.com/auth0-blog/rails-api-auth0).

## Securing an API

I didn't explain what I mean by securing an API yet. Essentially, we're ensuring that protected routes are accessible only for the users with enough rights.

When it comes to security, it's generally considered a bad idea to roll your own bespoke implementation. Instead, I'm using [OAuth](https://auth0.com/docs/protocols/protocol-oauth2), a battle-tested and widely used authorization framework for web applications.

In this context, Auth0 fulfills the role of the _authorization server_ and abstracts a significant part of the work away from us. That way, we can focus on delivering value to our users.

Without getting into too many details on how OAuth works, we assume that calls to our API will include a bearer token using the industry-standard [JWT](https://jwt.io/) format. The token contains a series of claims regarding its issuer, how long it is valid, and what rights it grants. Let's have a look at a sample token:

```json
{
  "iss": "https://yourTenant.eu.auth0.com/",
  "sub": "zHwnsh0j2sTj4u3ss6YedSFrzyb2",
  "aud": "https://targetAudience.com",
  "iat": 1621369130,
  "exp": 1791455530,
  "azp": "ThEkgdG1NndLlWoNMcEdEr2KJIs9vKad",
  "scope": "openid profile read:admin-messages",
  "permissions": ["read:admin-messages"]
}
```

We're going to implement verification for that token and reject requests that don't have the required permissions.

## Getting Started

We're getting started with our base application, bootstrapped with Rails 6. This [branch](https://github.com/auth0-blog/rails-api-auth0/tree/starter) is a good starting point. You can download it by running the following command in a terminal window:

```shell
git clone -b starter --single-branch https://github.com/auth0-blog/rails-api-auth0.git
```

The API has three endpoints with different levels of protection:

- `/api/messages/public`: Public route.
- `/api/messages/protected`: Requires a valid access token.
- `/api/messages/admin`: Requires a valid access token. Since Auth0 uses JWT as its access token format, we can inspect it and make sure it has a `permissions` claim that contains the scope `read:admin-messages`.

### Running the Application

To run the application, we first need the correct ruby version. The easiest way to do so is to use a version manager like [rbenv](https://github.com/rbenv/rbenv). Once you install it, run this command inside the repository to install the right version of ruby:

```shell
rbenv install
```

Install the dependencies for the application:

```shell
bundle install
```

And finally, run the application:

```shell
bin/rails s
```

You can verify that the application is working correctly with `curl`:

```shell
curl localhost:6060/api/messages/public
```

The command will return a 200 code, plus the message:

```json
{"message": "The API doesn't require an access token to share this message."}
```


[Read more...](https://auth0.com/blog/secure-rails-api/?utm_source=content_synd&utm_medium=sc&utm_campaign=rails)