User Authentication with JSON Web Tokens

By Joshua Kemmerling
Architect, projekt202

Security today is more important than ever. Most people I know have online accounts at a bunch of different social networks or online retailers. Some of these websites require personal information and some don't. But every new website you create an account for increases your vunerability to being hacked. So, as web developers, we need to make security a priority during development. It doesn't matter if it's a mobile app, API or a client-side application. Security needs to always be taken into consideration.

Security is not only incredibly important today, but it's also easier to implement today than it was years ago. Developers have huge amounts of resources available to be able to learn about the most recent security standards and techniques, and most all of these techniques have been tested and proven. So, there isn't any good reason that a website should be lacking with its security.

There are many security concepts and techniques that exist, but I want to talk about JSON web tokens.

What are JSON Web Tokens, You Say?

JSON web tokens are a way to authenticate an API request. Each JSON web token is digitally signed, so JSON can be sent between clients securely. A JSON web token is made up of three parts -- header, payload and signature -- and looks like xxxxxx.yyyyyy.zzzzzz. They are very compact and can also contain necessary information in its payload, so you won't need to query a database as much as you normally would. JSON web tokens are stateless, so it is simpler for the server to authenticate API requests.

Let's see how we can use JSON web tokens in the real world.

Authenticate Users

In this first example, we are going to use JSON web tokens to authenticate the API request after a user has logged in. This is the most common situation where we at projekt202 use JSON web tokens. Note that all examples use Node and expressjs on the server.

1. Install jsonwebtoken Package

The first thing we need to do is install the required packages command in the command prompt:

[code language="shell"] $ npm install jsonwebtoken $ npm install express [/code]

2. Require the need packages

We need to require jsonwebtoken and the crypto library at the top of our file. The crypto library is built into Node, so it's already on your computer.

[code language="javascript"] var crypto = require('crypto'); var jwt = require('jsonwebtoken'); var express = require('express'); [/code]

3. Create the secret key

The next thing we want to do is create a secret string that will be used to digitally sign each token. This is what gives us the ability to trust JSON web tokens. When you create the secret key, it is extremely important that no one knows what the secret key is. If someone knows the secret key, then that person is able to create valid tokens to send to the server. To make sure that no one knows the secret key -- not even the developers that wrote the code -- we are going to use the crypto library and tell it to return us 20 random bytes, then we convert that to a string. We are going to set that value to a variable when the file loads up. This means that the only person that will be able to know the secret key will have to purposely write code to output the secret. You create the secret key like:

[code language="javascript"] process.env.jwtsecret = crypto.randomBytes(20).toString('hex'); [/code]

4. Create the token

The next step is to create the token. We do this by calling a function in the jsonwebtoken framework like:

[code language="javascript"] var token = jwt.sign({ role: 'admin', }, process.env.jwtsecret, { algorithm: 'HS512', expiresIn: 300 }); [/code]

The default algorithm used when creating the token is HS256. We want to replace that with HS512 for increased security. We also want to set an expiration time so that keys cannot live forever. In this situation, we are going to set the expiresIn to 5 minutes, but we have to give the time in seconds to the function. We are also using this to limit the amount of time a user can be logged in.

5. Attach the token to the response header

After the token is created, you want to send that token in the response header back to the client making the API request. Every API request will have the token in the header to verify the request. You will verify the token, then, if valid, create a new token and send it back to client to save for the next request. Using expresses, we can do this with middleware.

Read more about expressjs middleware here.

[code language="javascript"] app.use(function (req, res, next) { try { jwt.verify(req.get('x-token'), process.env.jwtsecret, { algorithms: [ 'HS512' ] }); } catch (e) { res.send(401);

return false; }

var token = jwt.sign({ role: 'admin', userId: 'h3bd-87db-23jh-8dh2-87d3-asd2-p2er' }, process.env.jwtsecret, { algorithm: 'HS512', expiresIn: 300 });

res.setHeader('x-token', token);

next(); }); [/code]

Full index.js file

Here is the entire index.js file for the server:

[code language="javascript"] var crypto = require('crypto'); var jwt = require('jsonwebtoken'); var express = require('express');

process.env.jwtsecret = crypto.randomBytes(20).toString('hex');

var app = express();

app.use(function (req, res, next) { try { jwt.verify(req.get('x-token'), process.env.jwtsecret, { algorithms: [ 'HS512' ] }); } catch (e) { res.send(401);

return false; }

var token = jwt.sign({ role: 'admin', userId: 'h3bd-87db-23jh-8dh2-87d3-asd2-p2er' }, process.env.jwtsecret, { algorithm: 'HS512', expiresIn: 300 });

res.setHeader('x-token', token);

next(); });

app.get('/', function (req, res) { res.send('Hello World!'); });

app.listen(3000, function () { console.log('Example app listening on port 3000!'); }); [/code]

More to Learn

This is a simple version that we use to authenticate users. I encourage you to customize this to your needs and read more about JSON web tokens. A good place to start is jwt.io. The site has more information and a way to test your tokens.

Look for another article in the near future on how to use JSON web tokens to authenticate application access to your API.

Stay up-to-date on projekt202 news, events and upcoming articles. Follow us on LinkedIn, Twitter, Facebook,YouTube and Instagram.