Angular 2 Authentication Rails 5

Auth0 + Angular 2 + Rails 5 Authentication

What we’re going to do

This post shows how to get Auth0 + Angular 2 + Rails 5 authentication working. It’s not meant to be a comprehensive guide, just an intro. But it’s a pretty complete intro.

I’ll show you how to get Auth0 plugged into an Angular 2 app, and then show you how to get that Auth0/Angular combo talking to the Rails back-end.

I’m assuming you’re comfortable with Rails and that you’ve at least touched an Angular 2 app before. I provide the code to keep your Angular 2 test suite from breaking but I’m not worried so much about the Rails side, since I assume you can handle keeping that in order yourself.

Configuring Auth0

First we’ll get our Auth0 account set up. Carry out the following steps:

  1. Go to auth0.com and create an account
  2. In the “manage” area, go to Client and click “CREATE CLIENT”
  3. For Name, enter “HomeLibrary: Development”
  4. Under “Choose a client type”, choose “Single Page Web Applications”
  5. Click Create
  6. On the next screen where it asks “What technology are you using for your web app?”, choose Angular 2
  7. Go to the Settings tab
  8. Paste “http://localhost:4200” into “Allowed Callback URLs” and “Allowed Origins (CORS)” and click “SAVE CHANGES”

First, clone my HomeLibrary Seed Project and cd into the client directory. (The client directory is where the Angular application lives.)

Next, create an authentication branch.

There are two NPM libraries we’ll need in order to get authentication working: angular2-jwt and auth0-lock.

Now put your Auth0 domain and Auth0 client ID into your Angular environment file. (Client ID can be found by going to the Clients section in Auth0, then your app, then the Settings tab.)

Free Guide

Getting Started´╗┐ ´╗┐with Angular and Rails

Get an Angular/Rails app up and running in as little as 20 minutes

Next we simply pull these values from the environment file into auth.config.ts.

We’ll create an Auth service that looks like this. What follows is mostly copy-and-pasted from Auth0’s example, with one critical difference: email is included in the auth params, meaning Auth0 will give us not only the user’s Auth0 ID (which is fairly meaningless to us on its own) but also the user’s email address.

I think it’s nice to be able to store the user’s email address in our database. That way if you happen to look at the user table on its own, the data has some meaning by itself without having to cross-reference Auth0, which could be tedious. I also feel like having a user table with no human-readable identifiers would be a really error-prone situation. It’s nice to be able to know what you’re looking at at a glance.

We want to show a Log In button on the home page, and in order to do that, we need to add an auth object to our AppComponent.

Here what we add to the template to make the Log In (and Log Out) button show up.

Now start the front-end server.

At this point you should be able to click Log In, create an account with Auth0, get sent back to the main page and see that the “Log Out” button is now visible.

This is great but so far we haven’t done anything to communicate with Rails. We also broke a couple Angular tests by changing our application title. Let’s fix that.

(And by the way, you should log out now to prepare for the next time we test the login functionality.)

Connecting the Rails back end

Now we’ll start getting our front-end Auth0 stuff to talk to the Rails back-end.

The first step is to create a User model. We’ll give it an email and an auth0_id_string. (I didn’t want to call it auth0_id because that might lead a person to guess, incorrectly, that auth0_id is a foreign key to some value in another table.)

Let’s add some sensible NOT NULL constraints too.

Now run the migrations to create the table.

Installing Knock

We’ll use a gem called Knock to help us take the JWTs that Auth0 sends us and translate those into users.

Add Knock to your Gemfile.

Run a bundle install and then run the Knock installer.

The Knock installer will create a config/initializers/knock.rb which you’ll want to edit to match the following.

Add include Knock::Authenticable to your ApplicationController.

We also need to add before_action :authenticate_user to BooksController.

And since Auth0 factors our Client ID and Client Secret into the JWT, Knock will need to know our Client ID and Client Secret for comparison purposes. If the JWT from Auth0 doesn’t contain the Client ID and Client we’re expecting, then we shouldn’t consider the JWT valid.

Lastly on the Rails side, we’ll need to add a from_token_payload to the User model. Knock expects this function to be defined. When we receive our Auth0 JWT, Knock will decode it and call from_token_payload, passing in the decoded values from the JWT.

Adding BookService

Our Angular app needs a way to hit the /api/books endpoint. We’ll create a BookService for this purpose.

Put an HTTP request in BookService that hits http://localhost:3000/api/books.json. Note that we’re using AuthHttp rather than Angular’s built-in Http library.

After the user is authenticated on the front-end, we want to call bookService.getList(). This will force an authentication to happen in Rails and a new user will be created if one doesn’t already exist with that email.

We’ll need to add BookService and AUTH_PROVIDERS to our AppModule.

Now complete the following steps:

  1. Go to http://localhost:4200, click Log In and authenticate.
  2. Start a rails console and do User.all
  3. You should see a single user record containing your email address. This tells you that authentication is working.

Lastly, let’s fix the Angular tests we broke.

Now you should be able to run ng test and see everything pass.

About the author

Jason Swett

5 Comments

Click here to post a comment