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?
Advertisement
Answer
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:
- Private
openssl genrsa -out private.pem -aes256 4096
- Public from private
openssl rsa -in private.pem -pubout > public.pem