Please be aware that you are viewing our bleeding edge unstable documentation. Unless you wanted to view the bleeding edge (and possibly unstable) documentation, we recommend you use our stable docs.

Go to Ably's stable canonical documentation »

I know what I'm doing, let me see the bleeding edge docs »

You are viewing our bleeding edge unstable documentation. We recommend you use our stable documentation »
Fork me on GitHub

Client & Server JWT Authentication Tutorial

Ably supports two types of authentication schemes. Basic authentication uses one of your private API keys and is the simplest scheme designed for use by your servers. Token authentication is mostly used by your device and browser clients whereby a short-lived secure token is issued to them by your auth servers. JSON Web Token authentication is an extension of the token based authentication scheme in Ably.

When using token authentication, we recommend you instantiate Ably with a method to obtain tokens, rather than a token itself. This is due to the fact that tokens eventually expire, resulting in the connection being lost. By providing a method to obtain tokens instead, the Ably client library will automatically get a new token once the current one expires, maintaining a continuous connection.

By definition, JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties. JWT auth is especially helpful in scenarios where users want to use a single authentication scheme for all of their users’ devices/browsers as well as other vendors and third party platforms such as Ably. JWT auth is also a convenient way to authenticate your IoT devices or servers which are built using the platforms that Ably doesn’t yet support. This is possible because you don’t have to instantiate an Ably client when using the JWT auth scheme.

Ably offers two different ways in which you can use a JSON Web Token to authenticate your users. You can either use the JWT as the token itself by formatting it correctly (called an Ably JWT), or pass to Ably a JWT of any structure which contains an Ably Token. We’ll use the former.

In this tutorial, we will build a simple login form which would authenticate a client with Ably, using JWT. We’ll make use of the jsonwebtoken npm library which is an implementation of JWT. This library allows our auth server to conveniently create a JSON Web Token by specifying only certain service specific data in the payload and headers while allowing us to skip the default data. So, let’s get started and see a typical client-server architecture using JWT authentication.

Skip to demo

If you wish to directly check out the source code for this tutorial, we recommend you clone the tutorial repo and run it locally by following the steps below:

git clone https://github.com/ably/tutorials.git
git checkout jwt-authentication-node
cd jwt-authentication-node

Before running your server, make sure to replace the API Key in the ‘server.js’ file with your own. The DEMO will not work otherwise.

node server.js

Visit localhost:3000 in your browser


JWT Demo

Step 1 – Set up a free account with Ably

In order to run these tutorials locally, you will need an Ably API key. If you are not already signed up, you should sign up now for a free Ably account. Once you have an Ably account:

  1. Log into your app dashboard
  2. Under “Your apps”, click on “Manage app” for any app you wish to use for this tutorial, or create a new one with the “Create New App” button
  3. Click on the “API Keys” tab
  4. Copy the secret “API Key” value from your Root key and store it so that you can use it later in this tutorial

    Copy API Key screenshot

Step 2 – Setting up the server

Start by creating a node.js file and call it server.js. Now, let’s require the jsonwebtoken npm library. Before doing this, make sure that you have node and npm installed on your system.

npm install jsonwebtoken

and require like so:

var jwt = require("jsonwebtoken")

In order to use JWT auth, we’ll need to break down the Ably API key into three separate parts as shown below:


API key parts

As you see, the first part before the dot forms the appId, the second part before the colon forms the keyId and the remaining part after the colon forms the keySecret. We’ll make use of these parts for our JWT token request as you’ll see further. Go ahead and add the API key parts in your file:

//You must use your own API key
//For a dummy API key I2E_JQ.79AfrA:sw2y9zarxwl0Lw5a
var appId = 'I2E_JQ'
var keyId = '79AfrA'
var keySecret = 'sw2y9zarxwl0Lw5a'
var ttlSeconds = 60

Note the additional ttlSeconds variable that has not been explained yet. This is the duration in seconds for which the JSON Web Token will be alive, after that it needs to be refreshed, or in other words, replaced with a new one.

A JWT is typically made up of three different entities of data: a header, a payload and a signature. However, since we are using the jsonwebtoken npm library, these details are abstracted away and we only need a key secret and any application specific payload data. You can also add other options such as when you need to use a non-default hashing algorithm, etc.

With Ably, you must send the time-to-live as well as the key id (which is a concatenation the appId and the keyId parts of the API key with a dot) as part of the jwt options parameter. You can optionally send capabilities for the client using this token or even a client ID, these will be part of the payload. Let’s set up these two objects as shown:

var jwtPayload =
    {
        'x-ably-capability': JSON.stringify({ '*': ['publish', 'subscribe'] })
    }
var jwtOptions =
    {
        expiresIn: ttlSeconds,
        keyid: `${appId}.${keyId}`
    }

Next, it’s time to set up the server. We’ll use express to build a simple server to serve files on your localhost:

var express = require('express'),
    app = express();
app.use('/', express.static(__dirname))

The Express server uses a middleware to serve the content, and using express.static(__dirname) we are letting the server know that we want any HTML files in the root folder to be served up.

Let’s now set up the ‘/auth’ route in this server that will be responsible for creating a JSON Web Token and sending this token back to the client, confirming it’s authentication.

app.get('/auth', function (req, res) {
    console.log('Sucessfully connected to the server auth endpoint')
    jwt.sign(jwtPayload, keySecret, jwtOptions, function (err, tokenId) {
        console.log('JSON Web Token signed by auth server')
        if (err) {
            console.trace()
            return
        }
        res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate')
        res.setHeader('Content-Type', 'application/json')
        console.log('Sending signed JWT token back to client')
        res.send(JSON.stringify(tokenId));
    })
})

The above code is invoked when a client application hits the ‘/auth’ route on your auth server. We have just used the jsonwebtoken npm library to sign a JSON Web Token using the Ably API key which we obtained from our dashboard. The callback function returns an error parameter and the tokenId. We then simply check for the error if any, otherwise simply send the JWT back to the client in order to confirm its authentication with Ably.

Note that a cache-control has been added to the response header in order to prevent a chached token from being obtained. This makes sure we never obtain a token which has potentially expired.

See this step in Github

Step 3 – Setting up the client

Let’s now build a very basic client with a simple login form. For the simplicity of this tutorial, we’ll authenticate all the users, irrespective of the data they enter in the username and the password fields. However, in reality, your auth server would verify this data according to profile information on your server and generate and return a JWT back to the client only if the verification was successful.

We’ll use a simple styling template which is usually readily available to be used on the internet. So, go ahead and paste the CSS code which is hosted on GitHub in css/style.css.

Now let’s build the HTML file for our front-end client. We’ll embed our JavaScript logic directly into this file for simplicity. Add the following to your index.html file:

<html>
<head>
  <script src="https://cdn.ably.io/lib/ably.min-1.js" type="text/javascript"></script>
  <link rel="stylesheet" href="css/style.css">
</head>
<body>
  <section class="container">
    <div class="login">
      <h1>Ably JWT auth example</h1>
      <form>
        <input type="text" placeholder="Enter Username" name="username">
        <br/>
        <input type="password" placeholder="Password" name="password">
        <br/>
        <p class="submit">
          <button type="submit" onclick="login(event)">Login</button>
        </p>
      </form>
    </div>
  </section>
</body>
</html>

As you can see, it’s a simple HTML skeleton with a form containing two input fields, one for each username and password as well as a button for logging in. We’ve also linked Ably via CDN and our external stylesheet that we just included above. When the button is clicked, it should invoke the login function that we’ll add now within the JavaScript.

The last part is to add the logic into this form, we’ll do so by instantiating Ably’s Realtime client library and requesting a JSON Web Token. Please note that for simplicity, we are ignoring the username and password credentials which otherwise must be verified by your auth server before signing a JWT and sending it back to the client.

Go ahead and add the following within the head tag of your HTML file, right below the link to your CSS file:

<script type="text/javascript">
console.log('On login page now')
function login(e) {
    e.preventDefault();
    console.log('Fetching JWT token from auth server')
    var realtime = new Ably.Realtime({ authUrl: '/auth' });
    realtime.connection.once('connected', function () {
    console.log('Client connected to Ably using JWT')
    alert("Client successfully connected Ably using JWT auth")
    })
}
</script>

As you can observe, we begin by instantiating Ably’s Realtime client library, then we pass the ‘/auth’ path of our auth server within the authUrl parameter. If you remember from above, the ‘/auth’ path of our auth server is responsible for signing a JWT using the private API key and then returning back the tokenId, in other words, the JSON Web Token itself.

With the returned JWT, the client will automatically attempt to connect to Ably using it. If we successfully connect to Ably, we will display an alert to let the client know that the connection was successful.

That’s it, simple as that!

See this step in Github

Step 4 – Checking the output

Now that we’re all set with all of our files in place, go ahead and test it out. Fire up your command line/terminal. Most of the code editors come with a handy integrated terminal. After making sure you are in the right folder, start your server by running:

node server.js

Now open up a browser and visit ‘localhost:3000’ since your express server is listening on this port. You should see the login form. Keep the browser console open if you wish to see the logged messages. Enter some dummy data into the username and password fields and hit login button.

If all went well, you should see an alert with the message ‘Client successfully connected Ably using JWT auth’.

Next steps

1. Find out how Basic Auth and Token Auth differ and how to choose the right authentication scheme
2. Read up on Basic Auth and how to use Basic Auth on your server using the REST library
3. Read up on Token Auth and how to use Token Auth on a client using the Realtime library
4. Understand and see some examples of how to define capabilities for tokens and token requests
5. Discover how identities in tokens allow clients and servers to trust other clients’ identities validated and provided by your servers
6. Learn more about other Ably features by stepping through our other Ably tutorials
7. Gain a good technical overview of how the Ably realtime platform works
8. Get in touch if you need help


Back to top