0

I've built this sign in route that creates a JWT token, but outside of the function that creates it, the token is undefined, so I'm unable to use it outside of that function.

router.post('/login', (req, res) => {
    const { errors, isValid } = validateLoginInput(req.body);
    if (!isValid) {
        return res.status(400).json(errors);
    }
    const email = req.body.email;
    const password = req.body.password;
    User.findOne({ email }).then(user => {
        if (!user) {
            return res.status(404).json({ emailnotfound: "Email not found"});
        }
    bcrypt.compare(password, user.password).then(isMatch => {
        if (isMatch) {
            const payload = {
                id: user.id,
                name: user.name
            };
            var token =jwt.sign(
                payload, 
                keys.secretOrKey, 
                { expiresIn: 31556926 },
                (err, token) => {
                    res.json({
                        success: true,
                        token: "Bearer " + token
                    });
                });
            console.log(token)
            } else {
                return res.status(400).json({ passwordincorrect: 
"Password incorrect"});
            }
        });
    });
});

When the code hits that console.log statement, it shows that the token is undefined instead of returning the token.

Tom Mooney
  • 23
  • 6

2 Answers2

0

It seems you might have a problem with the token being created. The code is not checking if the token got created successfully.

(err, token) => {
                  res.json({
                  success: true,
                  token: "Bearer " + token
                  })
                }

Change this to :

(err, token) => {
                 if (err){
                   console.log("Error while creating token:"+err.message);
                   console.error(err);
                   //send an error response as well if needed.
                 } else {
                    res.json({
                    success: true,
                    token: "Bearer " + token
                    })
                 }

This will help you figure out what the problem might be.

Yogesh_D
  • 17,656
  • 10
  • 41
  • 55
0

The problem seems to be here:

var token =jwt.sign(
                payload, 
                keys.secretOrKey, 
                { expiresIn: 31556926 },
                (err, token) => {
                    res.json({
                        success: true,
                        token: "Bearer " + token
                    });
                });

Can you check the JWT library that you are using to see if it actually accepts a callback? The correct syntax on most JWT libraries for the sign function is:

var token = jwt.sign(payload, secretKey, options);
console.log("Token :" + token);

The options usually contains an expiresIn defined in seconds.

  • I'm using the most recent jsonwebtoken npm package. It hits that call back, but it doesn't store the token outside of it – Tom Mooney Sep 13 '19 at 02:17
  • As marked above, the question is similar to: https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – Vineet Kulkarni Sep 13 '19 at 04:12