ben tedder : code things

Part 2: Node.js implementation of JWT's (json web tokens)

As a follow up to my simple explanation of jwt's I wanted to describe how to implement a super basic jwt setup in node.js in about 10 minutes.

1. Install pre-requisites (there are only 3)

Skip the generators and scaffolds for this, just run the following commands and create a new node project with Express:

  • npm init
  • npm install express jsonwebtoken body-parser

2. Create a basic server

Don't overcomplicate it. A basic node + express server in your index.js file will get you there:

var express = require('express');
var bodyParser = require('body-parser');

const app = express();
app.use(bodyParser.json());

app.get('/api', function api(req, res) {
  res.json({
    description: 'My API. Please authenticate!'
  });
});

app.listen(3000, function () {
  console.log('App listening on port 3000!');
});

3. Add a login route and create a token

In your index.js file import jwt and then create a new route:

var jwt = require('jsonwebtoken');

...

app.post('/api/login', (req, res) {

  // insert code here to actually authenticate, or fake it
  const user = { id: 3 };

  // then return a token, secret key should be an env variable
  const token = jwt.sign({ user: user.id }, 'secret_key_goes_here');
  res.json({
    message: 'Authenticated! Use this token in the "Authorization" header',
    token: token
  });
}

4. Create a protected route that needs a correctly signed JWT

Put the following bits in your index.js file. Note the req.token = bearerToken below. This gives you access to the token on the actual request to verify it. Once you have verified it, you can do whatever you need to with it (ie, get user-specific info, check permissions, etc). In our case we're just returning a protected message to show that verification worked. Feel free to return the 'data' to see the { user: user.id } object we stored in the jwt's payload earlier.

app.get('/api/protected', ensureToken, (req, res) {
  jwt.verify(req.token, 'secret_key_goes_here', function(err, data) {
    if (err) {
      res.sendStatus(403);
    } else {
      res.json({
        description: 'Protected information. Congrats!'
      });
    }
  });
}

function ensureToken(req, res, next) {
  const bearerHeader = req.headers["authorization"];
  if (typeof bearerHeader !== 'undefined') {
    const bearer = bearerHeader.split(" ");
    const bearerToken = bearer[1];
    req.token = bearerToken;
    next();
  } else {
    res.sendStatus(403);
  }
}

5. Test it all out

Run node index.js to start up the server.

Start up Postman and try the following to make sure it's all working:

  • send a GET request to /api, confirm you get a message
  • send a GET request to /api/protected, confirm you get a 403 (Forbidden) response
  • send a POST request to /api/login and confirm you get a token in the response
  • finally, add that token to an Authorization header with a value of Bearer token.goes.here and send a GET request to /api/protected. This time the request should succeed and you should see the protected message

Wrap-up

Hopefully you were able to get that running. I imagine the same process is pretty similar in Rails. One of these days I'll create a part 3 covering how to do it in Ruby on Rails. Until then, let me know if you ran into any issues!