Skip to main content
ActionCable Introduction:

Disabling ActionCable for Unauthenticated Users

15

Episode 128 · July 11, 2016

To only have ActionCable's JS connect for logged in users, we can setup our Javascript to know when a user is authenticated or not, and have our websocket try to connect accordingly.

ActionCable Javascript


Transcripts

Disabling ActionCable for Unauthenticated Users

In this episode, I want to talk about disabling ActionCable for users that aren't logged in. In our notifications episode, we talked about sending notifications over websocket, but only if the user is logged in. There's no sense in the browser constantly attempting to connect to the websocket, only to be rejected because the user isn't logged in.

As you can see in the network tab, there are a bunch of status 101 requests, meaning the protocol is switching but the connection dies immediately. This is explained by checking the Rails logs, and we see that An unauthorized connect attempt was rejected". In connection.rb, we reject the connection if the user is not verified.

The issue here is the JavaScript does not know if a user is logged in. This is typical, since the JavaScript should never have any idea of the session, because the session needs to be encrypted. If the session wasn't encrypted, then users could impersonate other users. So on the JavaScript side, we need to figure out how to determine if a user is logged in.

The easiest way to determine this is to include a meta tag within the HTML head. Below is an example using Devise logic and methods:

<% if user_signed_in? %>
  <%= tag :meta, name: "current-user", data: {id: current_user.id} %>
<% end %>

Here we use a tag helper. With this tag in the head, the JavaScript now has the information it needs to determine whether or not to initiate an ActionCable connection. To verify if the meta tag is working, we log in and check the page source.

<meta name="current-user" data-id="1">

The tag documentation can be found here. Note that this helper is used by some of the more common helpers such as image_tag.

Now we need to update our JavaScript to look for the current user. In notifications.js, we can include a conditional using a jQuery wrapped object to check for a current user and place the rest of our subscription code inside.

if ($("meta[name='current-user']").length > 0) {
  // subscription code ommitted
}

We wrap the subscriptions instead of the ActionCable.createConsusumer() code inside cable.js, because ActionCable is smart enough to not attempt connecting if there are no subscriptions. We can verify this by logging out, and then inspecting the network tab inside the browser's developer tools. We now see that our JavaScript works as no websocket connections are being made. Thanks for watching and reading!

Written by Frank Lam

Loading...

Subscribe to the newsletter

Join 18,000+ developers who get early access to new screencasts, articles, guides, updates, and more.

By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

More of a social being? We're also on Twitter and YouTube.