ziouziw15
ziouziw15

Reputation: 15

JsonWebTokenError: jwt malformed

I want to make a middleware to check the user. I'm using JWT and cookies for this. I retrieved the cookie and decrypted it (it has been encrypted in the login controller function). Then I used jwt.verify(). But I've received this error message : JsonWebTokenError: jwt malformed. I've seen that it may mean that the token wasn't "the right formated" one. But I can't figure it out.

checkUser function :

exports.checkUser = async(req, res, next) => {
    const cryptedToken = req.cookies.snToken;
    console.log("cryptedToken01", cryptedToken); //displays a string consists of 3 parts, separated by / 
    const token = cryptojs.AES.decrypt(cryptedToken, process.env.COOKIE_KEY).toString();
    console.log("token01", token); // displays a longer monolithic string

    if (token) {
        jwt.verify(token, process.env.COOKIE_KEY, async(err, verifiedJwt) => {
            if (err) { 
                console.log("err inside jwt verify", err); // displays an error mesassage (JsonWebTokenError: jwt malformed)
                console.log("res.locals", res.locals); //displays res.locals [Object: null prototype] {}
                res.locals.user = null;
                res.cookie("snToken", "", { maxAge: 1 });
                next();
            } else {
                let user = await User.findByPk(verifiedJwt.userId);
                res.locals.user = user;
                next();
            }
        });
    } else { 
        res.locals.user = null;
        next();
    }
};

my login function :

exports.login = async(req, res) => {
    try {
        const user = await User.findOne({ where: { email: req.body.email } });
        if (!user) {
            return res.status(403).send({ error: 'The login information (email) is incorrect!' });
        }
        bcrypt
            .compare(req.body.password, user.password)
            .then((isPasswordValid) => {
                if (!isPasswordValid) {
                    return res.status(403).send({ error: 'The login information (pwd) is incorrect!' });
                } else {
                    const newToken = jwt.sign(
                        { userId: user.id },
                        process.env.COOKIE_KEY, { expiresIn: "24h" }
                    );
                    const newCookie = { token: newToken, userId: user.id };
                    const cryptedToken = cryptojs.AES.encrypt(JSON.stringify(newCookie), process.env.COOKIE_KEY).toString();
                        res.cookie('snToken', cryptedToken, {
                        httpOnly: true,
                        maxAge: 86400000
                    });

                    //res.status(200).send({ message: 'The user is successfully connected!', data: user });
                    res.status(200).send({ message: 'The user is successfully connected!', data: user, cryptedToken: cryptedToken });
                }
            });
    } catch (error) {
        res.send({ error: 'An error has occured while trying to log in!' });
    }
}

The call of these middlwares in my app.js:

app.get('*', checkUser);

Upvotes: 1

Views: 6314

Answers (1)

jps
jps

Reputation: 22515

In your current code, you get a Hex encoded ASCII string after decryption 7b22746f6b656e223a2265794a68624763694f694a49557a49314e694973496e523563434936496b705856434a392e65794a3163325679535751694f6a45314c434a70595851694f6a45324e4445314e6a45324d545173496d5634634349364d5459304d5459304f4441784e48302e693670564f486443473456445154362d3749644545536f326251467765394d4b34554a316f363676564334222c22757365724964223a31357d, which contains your cookie as a stringified JSON.

Instead of toString() after decrypting, which causes the hex encoded output, call toString(cryptojs.enc.Utf8) to get a JSON String and then parse it to an object:

const bytes = cryptojs.AES.decrypt(cryptedToken, process.env.COOKIE_KEY);

const cookie = JSON.parse(bytes.toString(cryptojs.enc.Utf8));

console.log("token", cookie.token); 

the result is a correct JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjE1LCJpYXQiOjE2NDE1NjE2MTQsImV4cCI6MTY0MTY0ODAxNH0.i6pVOHdCG4VDQT6-7IdEESo2bQFwe9MK4UJ1o66vVC4

Upvotes: 1

Related Questions