Using JSON Web Tokens with Node.js

By Lukas White

Front end frameworks and libraries such as Ember, Angular, and Backbone are part of a trend towards richer, more sophisticated web application clients. As a consequence of this, server-side components are unburdened from many of their traditional responsibilities, in essence becoming more like API’s. This API approach allows a greater decoupling of the traditional “front end” and “back end” parts of an application. One set of developers can build the back end independently from the front end engineers, with the additional benefit that testing becomes simpler. This approach also makes it much easier to build, say, a mobile application that shares the same back end as your web application.

One of the challenges when providing an API is authentication. In traditional web applications, the server responds to a successful authentication request by doing two things. First, it creates a session using some storage mechanism. Each session has its own identifier – usually a long, semi-random string – which is used to retrieve information about the session on future requests. Secondly, that information is sent to the client by way of headers instructing it to set a cookie. The browser automatically attaches the session ID cookie to all subsequent requests, allowing the server to identify the user by retrieving the appropriate session from storage. This is how traditional web applications get around the fact that HTTP is stateless.

APIs should be designed to be truly stateless. This means no login or logout methods and no sessions. API designers can’t rely on cookies either, as there is no guarantee that requests will be made via a web browser. Clearly, we need an alternative mechanism. This article looks at one possible mechanism designed to tackle the problem – JSON Web Tokens, or JWTs (pronounced jots). The examples in this article uses Node’s Express framework on the back end, and Backbone on the client.


Let’s briefly look at a few common approaches to securing APIs.

One is to use HTTP Basic Authentication. Defined in the official HTTP specification, this essentially involves setting a header on the server response which indicates authentication is required. The client must respond by attaching their credentials, including their password, to every subsequent request. If the credentials match, the user information is made available to the server application as as variable.

The second approach is very similar, but using the application’s own authentication mechanism. This usually involves checking the supplied credentials against those in storage. As with HTTP Basic Authentication, this requires that the user’s credentials are supplied with each and every call.

The third approach is OAuth (or OAuth2). Designed to a large extent for authenticating against third-party services, it can be rather challenging to implement, at least on the server-side.

A fourth approach is using tokens. That’s what we’re going to look at in this article. We’ll look at an implementation that utilizes JavaScript on both the front and back ends.

The Token Approach

Instead of supplying credentials such as a username and password with every request, we can allow the client to exchange valid credentials for a token. This token gives the client access to resources on the server. Tokens are generally much longer and more obfuscated than a password. For example, the JWTs we’re going to be dealing with are on the order of ~150 characters. Once the token is obtained, it must be sent with every API call. However, this is still more secure than sending a username and password with every request, even over HTTPS.

Think of the token like a security pass. You identify yourself at the front desk of a restricted building on arrival (supply your username and password), and if you can be successfully identified you’re issued a security pass. As you move around the building (attempt to access resources by making calls to the API) you are required to show your pass, rather than go through the initial identification process all over again.

About JWTs

JWTs are a draft specification, although in essence they are really just a more concrete implementation of an authentication and authorization mechanism that is already commonplace; that of exchanging tokens. A JWT is split into three parts, separated by periods. JWTs are URL-safe, meaning they can be used in query string parameters.

The first part of a JWT is an encoded string representation of a simple JavaScript object which describes the token along with the hashing algorithm used. The example below illustrates a JWT using HMAC SHA-256.

  "typ" : "JWT",
  "alg" : "HS256" 

After encoding, the object becomes this string:


The second part of the JWT forms the core of the token. It too represents a JavaScript object, which contains a few pieces of information. Some of these fields are required, and some are optional. An example, taken from the draft specification, is shown below.

  "iss": "joe",
  "exp": 1300819380,
  "": true

This is called a JWT Claims Set. For the purposes of this article, we’re going to ignore the third parameter, but you can read more in the specification. The iss property is short for issuer, and specifies the person or entity making the request. Typically, this would be the user accessing the API. The exp field, short for expires, is used to limit the lifetime of the token. Once encoded, the JSON token looks like this:


The third, and final, part of the JWT is a signature generated based on the header (part one) and the body (part two). The signature for our example JWT is shown below.


The resulting complete JWT looks like this:


There are a number of additional, optional properties supported in the specification. Among them are iat representing the time at which the token was issued, nbf (Not Before) to indicate the token should not be accepted before a certain time, and aud (audience) to indicate the recipients the token is intended for.

Handling the Tokens

We’re going to use the JWT Simple module to handle the tokens, which saves us from having to delve into the nitty gritty of encoding and decoding them. If you’re really interested you can find more information in the specification, or read through the repo’s source code.

Begin by installing the library using the following command. Remember that you can automatically add it to your project’s package.json file by including the --save flag in the command.

npm install jwt-simple

In your application’s initialization section, add the following code. This code imports Express and JWT Simple, and creates a new Express application. The final line of the example sets an application variable named jwtTokenSecret to the value YOUR_SECRET_STRING (make sure to change this value to something else).

var express = require('express');
var jwt = require('jwt-simple');
var app = express();

app.set('jwtTokenSecret', 'YOUR_SECRET_STRING');

Getting a Token

The first thing we need to do is enable the client to exchange their username and password for a token. There are two possible approaches to this in a RESTful API. The first is by issuing a POST request to an authentication endpoint, with the server responding to a successful request with a token. Alternatively, you could implement an endpoint from which a client can GET a token, which requires that they provide their credentials either as query parameters or, better still, via the headers.

The purpose of this article is to explain authentication tokens rather than the basic username / password authentication mechanism, so let’s assume we already have the following and we’ve already obtained the username and password from the request:

User.findOne({ username: username }, function(err, user) {
  if (err) { 
    // user not found 
    return res.send(401);

  if (!user) {
    // incorrect username
    return res.send(401);

  if (!user.validPassword(password)) {
    // incorrect password
    return res.send(401);

  // User has authenticated OK

Next, we need to respond to a successful authentication attempt with a JWT token:

var expires = moment().add('days', 7).valueOf();
var token = jwt.encode({
  exp: expires
}, app.get('jwtTokenSecret'));

  token : token,
  expires: expires,
  user: user.toJSON()

You’ll notice the jwt.encode() function takes two parameters. The first is an object which will form the body of the token. The second is the secret string we defined earlier. The token is constructed using the previously described iss and exp fields. Notice that Moment.js is used to set the expiration to 7 days from now. The res.json() method is used to return a JSON representation of the token to the client.

Verifying the Token

In order to verify the JWT, we need to write some middleware which will:

  1. Check for an attached token.
  2. Attempt to decode it.
  3. Check the validity of the token.
  4. If the token is valid, retrieve the corresponding user record and attach it to the request object.

Let’s start by creating the bare bones of the middleware:

// @file jwtauth.js

var UserModel = require('../models/user');
var jwt = require('jwt-simple');

module.exports = function(req, res, next) {
  // code goes here

For maximum flexibility, we’ll allow the client to attach a token in one of three ways – as a query string parameter, a form body parameter, or in an HTTP header. For the latter, we’ll use the header x-access-token.

Here’s the code, which goes in our middleware, that attempts to retrieve the token:

var token = (req.body && req.body.access_token) || (req.query && req.query.access_token) || req.headers['x-access-token'];

Note that in order to access req.body we need to have attached the express.bodyParser() middleware first.

Next, let’s try to decode the JWT:

if (token) {
  try {
    var decoded = jwt.decode(token, app.get('jwtTokenSecret'));

    // handle token here

  } catch (err) {
    return next();
} else {

If the decoding process fails, the JWT Simple package will throw an exception. If this happens, or if no token has been provided, we simply call next() to continue processing the request – it just means we haven’t identified the user. If a valid token exists and is decoded, we should end up with an object with two properties – iss containing the user ID, and exp with an expiration timestamp. Let’s check the latter first, and reject the token if it has expired:

if (decoded.exp <= {
  res.end('Access token has expired', 400);

If the token is still valid, we can retrieve the user and attach it to the request object as shown below.

User.findOne({ _id: decoded.iss }, function(err, user) {
  req.user = user;

Finally, attach the middleware to a route:

var jwtauth = require('./jwtauth.js');

app.get('/something', [express.bodyParser(), jwtauth], function(req, res){
  // do something

Or, perhaps attach it to a bunch of routes:

app.all('/api/*', [express.bodyParser(), jwtauth]);

Our middleware now examines requests looking for a valid token, and if one exists, attaches a user object to the request. It should be fairly trivial now to build some simple middleware to deny a request without a valid token, though you may wish to build that into the same piece of middleware.

That’s the server side element of the token approach. In the next section, we’ll look at how tokens work on the client side.

The Client

We’ve provided a simple GET endpoint for obtaining an access token. It’s straightforward enough that we probably don’t need to go over the details – just make a call, passing the username and password (from a form, perhaps) and if the request is successful, store the resulting token somewhere for later use.

What we will look at in more detail is attaching the token to subsequent calls. One way to do this is to use jQuery’s ajaxSetup() method. This can be used for straightforward Ajax calls, or for front end frameworks which use Ajax under the hood to communicate with the server. For example, suppose we put our access tokens in local storage using window.localStorage.setItem('token', 'the-long-access-token'); we can attach tokens to all calls via the headers like this:

var token = window.localStorage.getItem('token');

if (token) {
    headers: {
      'x-access-token': token

Put simply, this will “hijack” all Ajax requests and, if there’s a token in local storage, it will attach it to the request using the x-access-token header.

This doesn’t handle token expiration, but that ought to be relatively straightforward. You’ll remember that we returned an expiration timestamp with the token. Additionally, you may wish to have the server notify the client of an expired token using headers which indicate they must re-authenticate.

Using with Backbone

Let’s apply the approach in the previous section to a Backbone application. The simplest way to do this is to globally override Backbone.sync() as shown below.

// Store "old" sync function
var backboneSync = Backbone.sync

// Now override
Backbone.sync = function (method, model, options) {

   * "options" represents the options passed to the underlying $.ajax call         
  var token = window.localStorage.getItem('token');

  if (token) {
    options.headers = {
      'x-access-token': token

  // call the original function
  backboneSync(method, model, options);

Additional Security

You could add an additional layer of security by storing a record of issued tokens on the server, then verifying them against that record on each subsequent request. This would prevent a third-party from “spoofing” a token, and also allows the server to invalidate a token. I won’t cover that here, but it ought to be relatively straightforward to implement.


In this article we’ve looked at some approaches to authentication on an API, looking specifically at JSON Web Tokens. We’ve used Node with Express to write a basic working implementation of the technique, and looked at how to use it client-side using Backbone as an example. The code for this article is available on GitHub.

There is more to the specification which we haven’t fully implemented, such as “claims” on resources, but what we have done is used the basic proposal to build a mechanism for exchanging credentials for an access token, in this case between the client and server of a JavaScript application.

Of course you could apply this approach to other technologies – for example a Ruby or PHP backend, or an Ember or AngularJS application. Alternatively, you could adopt it for mobile applications. For example, by using web technologies in conjunction with something like PhoneGap, using a tool such as Sencha or as a fully native application.

  • Steven Hunt

    Great article! I recently implemented something very similar in NodeJS with SimpleJWT, although I wasn’t aware there were conventions for the JSON property names and moment.js would certainly make my expiration calculations look nicer…

  • Etienne

    Hi Lukas,
    many thanks for this great article, it’s very clear !
    Question : ok with local Strategy, because You can request the server for authentication with Ajax.
    But what about OAuth Strategy like Twitter or Facebook. In these cases, You are redirected to twitter or facebook. You accept the asked autorization, and you are redirected. But do I have to redirect ?
    – if I redirect to server, who can I give the generated token to my Client App ?
    – if I redirect to client directly, my server would be not aware of the authentication and token.

    I’m a little bit confused with that :( Could You help me ?
    (sorry for my english…)

    • ggsp

      Hey Lukas,
      Couldn’t you return the token to the client, then add to a header on AJAX calls to the service. The service can then validate the token (and user, likely with a shared secret like a client_id/secret) with the OAuth provider and create it’s own JWT at that point?

      Does that make sense?

      • Etienne

        but how do you return this token to the client ? because it’s your server how do the oauth authentication.
        1. Web App (Backbone app for my case) call node.js server for authentication
        2. node.js server uses Passport to make an oauth authentication using Twitter
        3. Go to Twitter to authorize you application
        4. Return successfully to node.js server (here, we can calculate the token)
        5. ??? how to return to my webapp ?

        With an username/password authentication (“local” Strategy of Passport in node.js server), it’s easier because web App can use Ajax to call node.js server, and get an immediatly response in json, containing the token.

        So my problem is in point 5 :(


        • ggsp

          Hmmmm….. how does Facebook/twitter do it now? They have a js flow (granted, it pops up a window) but it returns a token to the client. Or am I high?

          • Kamalanathan T

            I am also facing the issue pointed by Etienne. For Facebook, I am using the state parameter to send the token and get the token back in FB callback. But Twitter doesn’t have that option. Is there any workaround for this problem?

  • DCKT

    Very nice article, this help me a lot ! Thank you :)

  • Jim Bancroft

    Terrific article, thanks for writing it.

  • neilff

    Nice article, cleared up a lot of the questions I had about JWTs. I do want to know, if a token expires, the user would be disallowed access. This could technically happen in the middle of a user doing something which would result in a poor experience if one second they are logged in and next they are booted out. Should a token be refreshed automatically as the expiration becomes closer, or should they be expected to login again?

  • MurWade

    awsome stuff. thanks for that .

  • Nelson Miller

    Thanks for the great introduction. We are currently building an iOS app and want to use JWT as a token system between the iOS client and the API server. I have one questions related to this:

    How do handle the case of a compromised security token?

    Let’s say for some reason the token get leaked and we need to change it. It seems like most examples I found have a simple solution of hard coding the token secret in the backend and client code. This seems like a very simple approach.

    How do you handle it?

    Is the “JSON Web Token (JWT) Bearer Token Profiles for OAuth 2.0” spec a starting point to look into?

    Thanks for every help.
    Best Nelson

  • avejidah

    Thanks man, nice article – easy to follow.

  • avejidah

    Correct me if I’m wrong here, but it seems like the issuer (iss) should be just that: the site that is issuing the token. The subject (sub) should be the entity for whom the token was created (e.g. “Joe”).

  • chrisbenseler

    Great article!
    By the way: is there any way to invalidate (or delete) the token from a user?

  • Sigmund_Jung

    What about old browsers without localStorage support? How to deal with cross-tab authentication since you cannot share the stored token, and requiring multiple user logins would be a nightmare?
    I experimented with a mixed cookie/token solution: the server creates a session AND a token, and on subsequent requests it checks if there is a session and a cookie and if they are valid; only after that it tries to check for a token. This way you can cover both browser clients and other API clients.
    Does it make sense?

  • 11samype

    Tried following your tutorial but ran into a hickup. is ../models/user something that needs to be added to nodejs because I do not have it and it is referenced in your code.

    • Arlando

      Its a data access object referring to the User in his persistence layer/database, most likely using MongoDB to store user information.

  • Immo Hüneke

    Thanks for a helpful explanatory article. It’s worth combining jwt with passport for local authentication. Then use a bearer strategy to get the authentication token from the Authorization header. See the example code under and – other strategies supported by different passport modules include Facebook, Google etc.

  • Jon Wu

    Good article. One thing to note is that you may not want to set the token for all AJAX requests using ajaxSetup. You should explicitly send it as needed. Otherwise, you might have some third-party library on your page which using jQuery also and you might start sending your token to other sites or over HTTP when you thought all your calls were over HTTPS (the latter only applying to mixed mode sites).

  • rsa

    Very clean, thanks a lot!

  • Ganesh Datta

    Awesome article! Love how you included info about the middleware. Definitely helped me out.

  • jack

    Nice article, learned a bunch thank you. Curious if i were to add logout functionality would I need to keep track of JWT’s that aren’t expired? Like store them in a db? This seems like a breech in security if I store them in a db. Any thoughts?


  • Cássio Nandi Citadin

    Lukas, thank you for sharing your approach! It’s helping me a lot.

    I am using a JWT token as access to my public API. The client must send the token as query param or body (x-access-token as you said).

    I have a question about this getting/sending token flow in a Public API scenario.

    Do you think that on every request, the client must generate another token (with a new “exp”) or can I give a permanent token that will never change?

  • Exiquio Cooper-Anderson

    Great article.

  • Tony Mutai

    Great article, i was looking for a good tutorial on JWT and nodejs for a while now but i must admit this has cleared up most of my questions. Thanks.

  • gixty

    I would like to know the answer of this as well.

    • rantie

      Not in time but, personally i provide new tokens each time user does login check request, i think it will prevent such situations if one minute user is logged in and other his logged out. But of course if we have a year expiration date, it doesn’t matter at all.

  • aishwarya singh

    I’m installing dependencies (bcrypt) but it gets automatically

  • rantie

    What about logging out all users you have? It’s impossible with JWT approach, so the best way is to save JWT into db as well, for extra layer and some additional features, like logout all users from backend or etc. Disadvantage is that we have additional DB operation to check tokens. But this create some kind of JWT sessions approach.

  • Meesam Zaidi

    on decode, token.split is not a function error throw

  • commenter

    Hi, great article.
    I would like to know how is this more secure than regular user/password without HTTPS.

    When I submit my username/password on login over HTTP the hacker could snif the network and take my password/username.

    So it doesnt matter what kind of algorithms or how complex they are to provide security.


  • Brihaspati Dev

    Please provide a tutorial for MySQL database. looking for connection using token rather than username and password.

  • kisor

    when will token expire that is created from jwt-simple?

  • John Packel

    Very helpful, thank you! Typo here: “If the credentials match, the user information is made available to the server application as as variable.” Assume you mean “as a variable”. Curious how this works. If anyone’s still monitoring this thread maybe point me to a good explanation?

Get the latest in JavaScript, once a week, for free.