node.jsexpressjwtjson-web-signature

How to solve JsonWebTokenError "invalid signature" after assigning some infos to the generated token?


Have a problem when trying to verify the token (it was working fine before i added some data to it before generating it) .. but now it does not seem to be working !

This is how i generate the token when user send a POST request (login)

require('dotenv')
const jwt       = require('jsonwebtoken');
const bcrypt    = require('bcryptjs')
const Role      = require('../models/Role');
const Section   = require('../models/Section');
const User      = require('../models/User');

// Login !
router.post('/', async (req, res) => {

    let sections_fetched = [];


    // Validate data 
        
    // Check username
    const user = await User.findOne({username: req.body.username });
    if(!user) return res.status(400).send('Wrong user login credentials !');

    // Check password
    const is_pass_valid = await bcrypt.compare(req.body.password , user.password);
    if (!is_pass_valid) return res.status(400).send('Wrong user login credentials !');


    // Get role Object:
    const _role = await Role.findOne({_id:user.role , is_deleted:false});
    if (!_role) res.json("Failed fetching role !");


    // loop through sections   
    for (let index = 0; index < _role.sections.length; index++) {

        const tmpRole = await Section.find({_id: _role.sections[index], is_deleted:false});
        sections_fetched.push({access:tmpRole[0].access , name:tmpRole[0].name});
    }


    // create jwt token
    const token = jwt.sign({username:user.username, role:{name:_role.name, sections:sections_fetched}}, 'secret', {expiresIn : '24h'}, process.env.JWT_TOKEN_SECRET);
    res.json({token:token});

});

this is my JWT verification middleare :

require('dotenv')
const jwt = require('jsonwebtoken');

module.exports = function (req, res, next) {

    const token = req.header('auth-token');

    if (!token) return res.status(401).send('Access Denied !');
    console.log(process.env.JWT_TOKEN_SECRET);
    console.log(token);

    try 
    {
        
        const verified = jwt.verify(token, process.env.JWT_TOKEN_SECRET);
        req.user = verified;  
        next();

    } 
    catch (error) 
    {
        res.status(400).send('Invalid token !');
    }
}

and this is a simple example of listing users (using the JWT verification middleware ! ) :

const verifyToken = require('../middlewares/verifyToken'); // my jwt middleware to verify !

// Listing All users
router.get('/', verifyToken, async (req, res) => 
{
    try 
    { 
        const users = await User.find({is_deleted:false});
        res.json(users);
    }
    catch (error) 
    {
        console.log("err ->\n"+error);
        res.json({message: error});
    } 
});


Solution

  • what is 'secret in the below line? seems you are adding a secret key twice, replace the hardcoded word 'secret' with token from env

    const token = jwt.sign({username:user.username, role:{name:_role.name, sections:sections_fetched}}, 'secret', {expiresIn : '24h'}, process.env.JWT_TOKEN_SECRET);