Skip to content

josegrobles/jwt-selfissuer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

63 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

jwt-selfissuer Build Status License: MIT

Logo

JWT Auto-Renewal Middleware for Express

Everything is explained down here but you can check it out in a better format on the wiki : Link to the Wiki

What is it?

jwt-selfissuer works by renewing a previous expired token with a new one, and returning it on the response headers. It's born from the idea of having an easy way of issuing tokens with security and easiness. By using it you provide an easy and secure way of controlling user access.

It works by using Redis to store a hash which is directly linked with the previous used token, this way it manages to only issue a new token when the hash stored in it matches one of the already registered on Redis. It also provides an easy way to revoke access to determined devices as each device is linked to an unique UUID.

How it works?

It works by checking the Authorization header on the requests, it will issue a new one depending on the previous one expiration time, it responses with an X-Token header whether it has expired or not, the only difference is that if it has expired the X-Token will be the new one.

Installation

First, let's install it by writting

npm install jwt-selfissuer

Once it has been installed, let's import it to the file where we want to mount the middleware

var jwt_issuer = require('jwt-selfissuer')

But first lets talk about how to make this works flawlessly!

#Issuing proper tokens ##Requirements A Token must include the next parameters:

  • Expire time
  • A hash previously stored in Redis

How to comply with this requirements

Expire time

To comply with the expiring time you just need to issue a token with a exp key on the payload. There are two ways of doing it using the package jsonwebtoken:

1. Adding a exp key to the payload

let payload = {username: "test"}
const expireAt = Math.round(new Date()/1000) + (15*60) //Expires in 15 minutes
payload.exp = expireAt
const token = jwt.sign(payload,key,options)

2. Adding the expiresIn key to the options object

let payload = {username: "test"}
let options = {}
options.expiresIn = 15*60 //Expires in 15 minutes
const token = jwt.sign(payload,key,options)

A hash previously stored in Redis

The way explained here is the best way I could think of, but I'm totally open to change my mind.

These two next step should be used as functions when registering or login an user

First we need to create a random hash for it to be stored along the payload:

let hash = crypto.randomBytes(8)
hash = hash.toString('hex')
payload.hash = hash
* You shold use this code along the previous one used Expire time

Secondly we need to store this hash on redis along other info such related to the device

let device_uuid = crypto.randomBytes(32)
device_uuid = device_uuid.toString('hex')
client.multi()
      .hset(username+"_devices",device_uuid,JSON.stringify(device_info))
      .hset(username+"_hashes",device_uuid,hash)
      .exec((err,info) => {
        if(err) console.log(err)
      })

We are generating an UUID which is related to every device

Now everything is ready!

Integrating it with Express

There are multiples way of doing it, but here I'm going to explain the easiest one:

Creating the configurations

The first paramater we need to pass is the key to encrypt the token
const key = "ThisIsTheKey"
The second paramater is the Redis Client
var redis = require('redis')
client = redis.createClient()
The third paramater are the verification options for the token (Optional)
const verification_options = {ignoreExpiration:true}
The last one paramater are the signing options for the token. Here you can change when the token Expires. (Optional)
const signing_options = {expiresIn:900}
Expire time is by default 15 minutes

Importing the function

var issuerMiddleware = jwt_issuer(key, client, verification_options, signing_options)

Implementing it as a Middleware

It is very simple, you just need to throw the previous declared variable into the endpoint that you want:

router.post('/user/info',issuerMiddleware,(req,res,next) => {
  res.send(req.info.username)
})

Everything stored in the token payload will be accessible to you in req.info Just like:

const info = req.info
console.log(info) //This should print everyhing stored in your jwt

About

JWT Auto-Renewal Middleware for Express

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published