I'm trying to make a simple authentication system on my Node.js API. Actually, I had the login endpoint working like a charm with JWT, but I also wanted to implement a logout function (and not have to wait for the token to expire) so I looked up how to achieve it.
After doing an exhaustive research on how to do it from the server side, I decided to install the jwt-redis package, which is suposed to not only repeat the entire functionallity of jsonwebtoken, but also store tokens in Redis and be able to destroy them with a simple method.
The fact is that now, after following the instructions on its readme, and although the endpoint is returning a successful status when testing with Postman, the response body (where the access token should be) is empty.
I attach my code below.
async login(req, res) {
try {
const redis = require('redis');
const JWTR = require('jwt-redis').default;
//ES6 import JWTR from 'jwt-redis';
const redisClient = redis.createClient();
const jwtr = new JWTR(redisClient);
redisClient.on("error", function (err) {
console.log("Error " + err)
})
await redisClient.connect()
console.log('email:' + req.body.email)
console.log('hola')
let user = await this.adapter.getByLogin(req.body.email)
if (!user) return res.status(404).json({ Error: 'Recurso no encontrado' })
const bcrypt = require('bcrypt')
console.log(req.body.password, user.password)
bcrypt.compare(req.body.password, user.password, (error, result) => {
console.log(error, result)
if (error) return res.status(404).json({ Error: 'Recurso no encontrado' })
if (!result) return res.status(404).json({ Error: 'Recurso no encontrado' })
delete user.password
var payload = { jti: req.body.email }
const accessToken = jwtr.sign(payload, process.env.ACCESS_TOKEN_SECRET)
//console.log('accessToken:' + JSON.stringify(accessToken))
res.json(accessToken)
})
} catch (error) {
return res.status(500).json({ error: 'Recurso no encontrado', stacktrace: error })
}
}
Please, take in care that I'm pretty new in JavaScript and Back-end development, so probably it is due to a dummie mistake. Anyway, I will appreciate your help, either if you have worked with this library before and you know where the error is, or you have any other idea of how I can make both login and logout work properly using JSON web token.
Thanks in advance.
The sign function of the jwt-redis package returns a promise, so you need to use either await or then in order to get the result of it.
First, in order to use await, you have to make the compare function's callback be async like
bcrypt.compare(req.body.password, user.password, async (error, result) => {}
after that, add the await keyword before the sign function call
const accessToken = await jwtr.sign(payload, process.env.ACCESS_TOKEN_SECRET)