Adding Token-Based Authentication to Rails API

Cory Baker
Apr 11, 2018 · 5 min read

It’s certainly safe to say that the days of authenticating user credentials via sessions and cookies are wearing thin. It’s not that session-based authentication is insecure — it’s just that CORS, Cross Site Request Forgery, and speed are all real things. Enter tokens.

src: https://auth0.com/blog/cookies-vs-tokens-definitive-guide/

Required Gems

gem 'bcrypt', '~>3.1.7 is what encrypts the authenticated information, such as password.

gem 'jwt' basically gives us access to a global variable JWT which will allows encoding and decoding of tokens.

gem 'simple command' acts as a sort of helper function. It makes authentication between controllers and models easier.

BCrypt

BCrypt is a cool gem. But most importantly it gives us access to a method called has_secure_password. We’ll be adding this method to our User model.

JSON Web Token

JsonWebToken is a class that’s added to lib/json_web_token.rb One of the notable features of this file is the ability to set the amount of time that a token is valid — sort of like cookies. The code below shows 2 hours.

This code is connected to our app by adding config.autoload_paths << Rails.root.join('lib') to our application.rb file.

In case you’re wondering, Rails’ secrets are simply where the encrypted keys are stored.

Authenticate User

With sessions, we would have to setup a sessions_controller.rb file. Out with the old, in with the app/commands/Authenticate_user.rb.

The meat of this file is the checking of a user instance against the authenticate method. authenticate is given to us by putting the mentioned has_secure_password method in our User model.

Authorize API Request

Go ahead and create an authorize_api_request.rb file in app/commands folder.

Adding Token-Based Authentication to Rails API

It’s certainly safe to say that the days of authenticating user credentials via sessions and cookies are wearing thin. It’s not that session-based authentication is insecure — it’s just that CORS, Cross Site Request Forgery, and speed are all real things. Enter tokens.

src: https://auth0.com/blog/cookies-vs-tokens-definitive-guide/

Required Gems

gem 'bcrypt', '~>3.1.7 is what encrypts the authenticated information, such as password.

gem 'jwt' basically gives us access to a global variable JWT which will allows encoding and decoding of tokens.

gem 'simple command' acts as a sort of helper function. It makes authentication between controllers and models easier.

BCrypt

BCrypt is a cool gem. But most importantly it gives us access to a method called has_secure_password. We’ll be adding this method to our User model.

JSON Web Token

JsonWebToken is a class that’s added to lib/json_web_token.rb One of the notable features of this file is the ability to set the amount of time that a token is valid — sort of like cookies. The code below shows 2 hours.

This code is connected to our app by adding config.autoload_paths << Rails.root.join('lib') to our application.rb file.

In case you’re wondering, Rails’ secrets are simply where the encrypted keys are stored.

Authenticate User

With sessions, we would have to setup a sessions_controller.rb file. Out with the old, in with the app/commands/Authenticate_user.rb.

The meat of this file is the checking of a user instance against the authenticate method. authenticate is given to us by putting the mentioned has_secure_password method in our User model.

Authorize API Request

Go ahead and create an authorize_api_request.rb file in app/commands folder.

To clear things up, this secure token that we’re using isn’t actually stored in the JSON body. AuthorizeApiRequest makes sure that our headers have this token.

Authentication Controller

authentication_controller.rb is the entry point of user data into our API. Assuming everything in our params checks out against our now built-in AuthenticateUser command, the server will send the access token back to the user — a “go ahead,” if you will.

current_user

The @current_user instance lives on. Our application_controller.rb is very similar to a sessions-based authentication. In a nutshell, it says to check check the incoming request for a token and sets up a @current_user with this token.

Final Thoughts

Literally, that’s it. Assuming you have a user model, controller, and route you could actually just copy and past this setup — which is what most people do. This setup assumes you are using an email to sign in. Simply replace “email” with “username” if that’s how you’d like your app to work.

Cory Baker

Written by

Full time nerd