Back to Blog

Real Time Rails 4: Using Server-Sent Events with Authy OneTouch

header

Server-Sent Events (SSE) are real-time events sent from a server and received by a browser, perfect for updating the front end when a server receives a webhook. We’re going to look at how to use SSE to implement Authy OneTouch using Rails 4.

Our end result should look a bit like this:

When logging in the site pops up a modal window that says it is waiting for OneTouch approval. The phone receives a push notification which opens up the approval. Selecting approve then causes the login screen to complete and the user to be logged in.

Authy OneTouch

Two-factor authentication usually means copying a bunch of numbers from your phone to the place you’re trying to log in. Authy OneTouch is a more user-friendly version of two-factor authentication. As you can see above, the user just needs to accept the authentication attempt and they are logged in.

On the backend, Authy sends a webhook to the application with the result of the authentication request. The application can then log the user in and choose how it updates the front end. Check out our tutorial on how to get started with Authy OneTouch and Rails for more detail on how it all works.

Real-Time Rails 4?

You might be thinking that Rails 5 is finally bringing real-time action to the Ruby world with Action Cable. If you are then you probably missed that Rails 4 included ActionController::Live, a means of streaming data from a Rails in real-time. Connect this up to the EventSource API in browsers and we have a full implementation of Server-Sent Events that we can use to send data from the server to the browser in real-time.

The tutorial for Authy that I mentioned earlier actually implements the OneTouch flow by polling the server for updates. As polling can be inefficient and result in many unnecessary requests to our server let’s replace it with SSE.

Tools

To follow this post and implement SSE in Rails you’re going to need a few things:installed

Once you’ve got all that, we’ll get the tutorial application set up.

Getting started

The best instructions for running the tutorial are available in the project README. Follow the instructions all the way through until the application is running locally, you have enabled OneTouch on your Authy application and set the webhook endpoint to your ngrok URL.

Once you’ve followed the instructions you should be able to visit your application at http://localhost:3000 and sign up as a new user. Logout and log back in again and you will be presented with the following two-factor authentication flow.

When logging in the site pops up a modal window that says it is waiting for OneTouch approval. The phone receives a push notification which opens up the approval. Selecting approve then causes the login screen to complete and the user to be logged in.

You can see in the console that the JavaScript is constantly polling our backend to see if the user is authenticated yet.

While the application waits for the user to approve the authentication request it polls the server once every 2 seconds which we see in the logs.

Let’s replace that polling mechanism with Server-Sent Events.

Adding Server-Sent Events

In order to run real-time features like SSE (and Action Cable when Rails 5 is released) it is recommended to use a threaded server, like Puma. The project currently uses Unicorn so we need to update that.

Open up the Gemfile and change

Now when you start the server it boots Puma and records the current thread configuration.

Updating The Controller

Next, we need to set up a streaming endpoint on our Rails server. Enable streaming capabilities for the existing controller by opening app/controllers/authy_controller.rb and including the ActionController::Live module.

Under the one_touch_status action, create a one_touch_status_live action:

2016-06-17_1529

When you run the JavaScript in the dev tools console you see time objects printing out once per second.

Let’s update this now to push real data from the server to the front end.

Pushing real data with PostgreSQL pub-sub

In the tutorial application when a user approves or denies the authentication request, the Authy webhook hits the /authy/callback endpoint which runs the callback action in the AuthyController. This then updates the user with the status from the parameter of the webhook.

In order to push that status to the client, we’d like to listen for that update whilst we have a live connection open to our streaming endpoint. Because we are using PostgreSQL in this example we can use its publish-subscribe feature. If you are using a different database without pub-sub you could achieve the same result by using something else like Redis to fill the gap.

PostgreSQL uses the keywords NOTIFY and LISTEN to publish and subscribe to events respectively. Active Record doesn’t directly support these keywords, but we can execute them using the database connection anyway.

We’ll add the notification code to the User model so open up app/models/user.rb. First, we want to send a notification when the user is saved and their authy_status has changed.

We can run the notification method every time the user model is saved using an Active Record callback.

Updating the JavaScript

Open up app/assets/javascripts/sessions.js and replace the code within the checkForOneTouch function with the following:

We run the same authentication flow as before, however this time we see that there are no polling events in the log. We have successfully implemented Server-Sent Events.

Hooray! Real-time updates to the front end, no polling required. Check out my fork of the original tutorial to see the complete changes.

Rails 4 does Real-Time

Rails 5 and Action Cable might not be released just yet, but Rails 4 can still perform some pretty sweet real-time manoeuvres. This works really well for server based updates as we’ve seen with Authy OneTouch. It would also work for live updating call statuses on a dashboard like Sam showed using Socket.io and React or creating a dashboard for conference events like Dominik did using Socket.io and Angular.

Server-Sent Events just provide one-way real-time events, though. Action Cable will bring two-way real-time streams to Rails for more complicated interactions, like a chat room. Of course, you don’t have to build all that complexity yourself if you use IP Messaging 😉

Do you like the look of SSE in Rails or are you going to be holding out for Action Cable? Let me know in the comments below, give me a shout on Twitter at@philnash or drop me an email at [email protected].

 

This blog post was originally published at Twilio.com

We can text you a link to get started:

Close