snakom23
snakom23

Reputation: 203

Refresh expired JWT token

this is my middleware in backend

const jwt = require('jsonwebtoken');
const User = require('../models/user');

module.exports = (req, res, next) => {
const auth = req.get('Authorization');

if (!auth) {
    return res.status(401).json({
        "response": {
            "message": 'Not authorized user',
        }
    })
}

const token = auth.split(' ')[1];
let decode;
try {
    decode = jwt.verify(token, process.env.JWT_SECRET_KEY)
} catch (err) {
    return res.status(401).json({
        "response": {
            "message": 'Invalid token access',
        }
    })
}

if (!decode) {
    return res.status(500).json({
        "response": {
            "message": 'Error token access',
        }
    })
}

let userId = decode.id;

User.findById(userId)
    .then(user => {
        req.user = user;
        next();
    }).catch(err => {
        console.log(err);
        res.status(401).json({
            "response": {
                "message": `Error on authorization`,
            }
        })
    })
}

I need integration of auto refresh token on each call when expire, and how can do for resave in localstorage in my client side?

Have my front-end developed with vue and vuex. Use this localStorage.setItem('access_token', token); code for save in localstorage.

Upvotes: 1

Views: 6327

Answers (1)

onuriltan
onuriltan

Reputation: 3898

Below is the logic that I did in my own web app

  1. When user logs in you need to create access and refresh token
  2. After you receive both tokens keep them in localStorage or wherever is safe
  3. You need to create a refreshToken route(/refresh-token) to call when your access token expired
  4. Define a middleware to check tokens and use it in secured routes
  5. When you get an 401 error call /refresh-token route to refresh the token config file
{
  "secret": "secret",
  "refreshTokenSecret": "refresh-secret",
  "port": 8080,
  "tokenLife": 900,
  "refreshTokenLife": 86400
}

login route(app.js)

router.get('/login',(req, res) => {
 const postData = req.body;
 const user = {
     "email": postData.email,
     "name": postData.name
 }
 const token = jwt.sign(user, config.secret, { expiresIn: config.tokenLife})
 const refreshToken = jwt.sign(user, config.refreshTokenSecret, { expiresIn: 
 config.refreshTokenLife})
 const response = {
   "status": "Logged in",
   "token": token,
   "refreshToken": refreshToken,
 }
 tokenList[refreshToken] = response
 res.status(200).json(response);
}

refresh token route(app.js)

router.post('/refresh-token', (req,res) => {
    const postData = req.body
    if((postData.refreshToken) && (postData.refreshToken in tokenList)) {
        const user = {
            "email": postData.email,
            "name": postData.name
        }
        const token = jwt.sign(user, config.secret, { expiresIn: config.tokenLife})
        const response = {
            "token": token,
        }
        // update the token in the list
        tokenList[postData.refreshToken].token = token
        res.status(200).json(response);        
    } else {
        res.status(404).send('Invalid request')
    }
})

tokenMiddleware.js

const jwt = require('jsonwebtoken')
const config = require('./config')

module.exports = (req,res,next) => {
  const token = req.body.token || req.query.token || req.headers['x-access-token']
  if (token) {
    jwt.verify(token, config.secret, function(err, decoded) {
        if (err) {
            return res.status(401).json({"error": true, "message": 'Unauthorized access.' });
        }
      req.decoded = decoded;
      next();
    });
  } else {
    return res.status(403).send({
        "error": true,
        "message": 'No token provided.'
    });
  }
}

use middleware to protect routes

router.get('/secured-route', tokenMiddleware, async (req, res) => {
    res.send("secured");
});

Upvotes: 2

Related Questions