Home > Blockchain >  Cannot verify JWT - UnhandledPromiseRejectionWarning: JsonWebTokenError: jwt malformed
Cannot verify JWT - UnhandledPromiseRejectionWarning: JsonWebTokenError: jwt malformed

Time:02-15

I have function that just send data to database (my posts). I use private and public keys to sign and verify tokens. I can send this token in header from front-end to back-end, but has problem with verifying it. Here is how this flow looks like:

Front-end

router.post(`/p-p`, async (req, res) => {
  try {
    const data = await api.post(`/post-post`, req.body, {
      headers: {
        Authorization: 'Bearer '   req.body.token
      }
    })
    res.json(data.data)
  } catch (e) {
    res.status(e.response.status).json(e.response.data)
  }
})

Back-end

router.post(
  "/post-post",
  auth,
  wrapAsync(generalController.postPost)
)

Middleware auth

const jwtService = require('./../services/jwtService')

module.exports = async(req, res, next) => {
  if (req.headers.authorization) {
    const user = await jwtService.getUser(req.headers.authorization.split(' ')[1])
    if (user) {
      next();
    } else {
      res.status(401).json({
        error: 'Unauthorized'
      })
    }
  } else {
    res.status(401).json({
      error: 'Unauthorized'
    })
  }
}

And JWT service

const jwt = require('jsonwebtoken');
const fs = require("fs");
const path = require("path");

const pathToKeys = path.resolve(__dirname, "../../keys");

module.exports = {
  sign(payload) {
    const cert = fs.readFileSync(`${pathToKeys}/private.pem`);
    return jwt.sign(
      payload,
      {
        key: cert,
        passphrase: process.env.JWT_PASSPHRASE
      },
      {
        algorithm: "RS256",
        expiresIn: "30m"
      }
    )
  },
  getUserPromise(token) {
    return new Promise((resolve, reject) => {
      jwt.verify(token, fs.readFileSync(`${pathToKeys}/public.pem`), (err, decoded) => {
        if(!err) {
          return resolve(decoded);
        } else {
          return reject(err);
        }
      })
    })
  },
  async getUser (token) {
    return await this.getUserPromise(token)
  }
}

The problem starts after getUserPromise function. This function can get a token, but can't verify it and I have this problem:

UnhandledPromiseRejectionWarning: JsonWebTokenError: jwt malformed

Actually, I have no idea where problem is. I generated key pair, and sign function can sing and return token, which looks like this: 351e38a4bbc517b1c81e180479a221d404c724107988852c7768d813dd0510e6183306b1d837091b2cddaa07f2427b7a

So, what's the problem?

CodePudding user response:

I have found the solution of this problem and it feels shame. In JWT service pay attention to this string:

algorithm: "RS256"

As you can see I use RS256, but I generated certificates in other format, so, because of this I got that error.

So, if you use RSA certificates, pay attention to algorithm!

EDIT:

Here is how you can generate pair for RS256:

  1. Private
openssl genrsa -out private.pem -aes256 4096
  1. Public from private
openssl rsa -in private.pem -pubout > public.pem
  • Related