Hi, and welcome to this course where we are going to learn how we can create a Rails API application that uses authentication and works with a React JS app. So the use case for this is if you want to built out your own authentication from scratch, especially if you’re building out authentication for a front end application. So if you want to add a registration and a sign in component to react or to angular or Vue JS, then this will walk through exactly how to do that.
Now we are going to be implementing HTTP only cookie authentication. There are two popular types of authentication. One is to use HTTP only cookies. The other is to use what are called JWT tokens. Now I prefer to use HTTP only cookies, mainly because it leads to a much more straight forward interface.
With JWT tokens, you generate these randomized encrypted tokens and then both sides of the application have to do quite a bit of work to one, make sure that the tokens are still accurate and that they’re still matching, that they haven’t been hijacked and the front end application has to store it in local storage or something like that.
And then the back end constantly has to check that, and it feels like that’s not really the best fit, especially if you’re a rails developer. With rails, you have the ability to utilize the session and so what the session does, if you’re familiar with MVC applications, you can store anything you want in a session, such as if a user’s logged in or not, and what we can do with an API can actually take advantage of this same exact set of features. So we can use the session the same way we would with a traditional MVC app, even though it’s an API.
So we’re gonna walk through all of the steps needed in order to do that. In this guide, we’re going to generate a Rails API application from scratch, and we’re going to add the dependencies needed for building our own authentication. From there we’re going to configure the app to work.
So let’s get started.
I’m going to create a new application here, running the command:
rails new authentication_app --database=postgresql
Now you may notice I did not use the API only flag. Rails does have the ability to create a API only application, however, if you do that, you actually won’t be able to use the session properly.
So I’m generating a regular application, just like a standard MVC app, but we’re not going to use any of the views, we’re going to treat it like an API only application.
So now that that’s been generated, let me jump into the authentication app and I’m gonna start up team ux here.
First, we need to create the database, by running:
And then after that, we’re going to add two gems to the
gem 'bcrypt', '~> 3.1', '>= 3.1.12' gem "rack-cors", :require => 'rack/cors'
And then run
bundle install to install the dependencies. With that in place, we can start building out our configuration.
We are going to start by adding a couple files, starting with the
Create a file:
config/initializers/cors.rb and add the following content:
Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins "http://localhost:3000" resource "*", headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head], credentials: true end allow do origins "https://your-production-app-here.com" resource "*", headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head], credentials: true end end
So what is the purpose of this cors file? Cors gives you the ability to white list certain domains because we’re going to be passing secure cookies back and forth between the front end application and the back end application. And we need to be able to use a tool called credentials, and so what’s required with Rails is that if you’re gonna use credentials, which means that you’re gonna work with the session, then you have to implement a tool like cors and give a specific set of rules for how you are going to be able to communicate. And these rules are defined in this initializer.
Let’s walk through what this code is doing. We start by inserting a level of middleware here and we’re using the cors module to do it. So all of the rules that we place inside this code block are going to be intercepted by the rails config so we’re saying at the very top of the chain, we want to establish these rules. Because if a application tries to communicate with our system that’s not authorized to do so, and they’re coming from a domain that we have not white listed, we don’t want to give them any access to the system.
From that point, we create an
allow block, and then give an origin. The origin is a string and is a list of domains that we want to whitelist. For this application we’re whitelisting localhost for local development for our front end application, and then the domain for where the front end application will be deployed.
Make sure you note that with the localhost code, the port is going to change depending on what kind of front end application you’re working with, and what port you’re using. For example, if you’re using Vue JS, then you’re probably going to use localhost 8080, or if you’re using some specific type of react application that runs on a different port by default, you’re gonna use whatever port it runs on.
After that, we have to list off the resources, headers, and HTTP methods that are allowed. We are going to allow all of the resources our whitelisted domains. This means that the domains that we whitelist will have the ability to create, update, delete, etc.
Lastly, we’re adding the
credentials: true flag at the end of the line. This is what is going to allow you to pass the HTTP only cookies back and forth between the front end and backend applications. If you do not put that there, it will not work.
After that, create a
config/initializers/session_store.rb file and add the following content:
Rails.application.config.session_store :cookie_store, key: "_authentication_app", domain: "your-production-app-here.com"
The session store is where we define what the cookie’s going to be structured like. So with session store, we’re saying:
- We’re going to use the Rails’
cookie_storesystem to manage our sessions.
- The name of the cookie will be:
- The domain will be
Obviously you’ll need to pass in your own domain in that section.
With that completed, we’re ready to start building out the registration and login features into the Ruby on Rails API.