Register a New User when using JWT strategy

Viewed 110

I am trying to use passport-local-mongoose for registering my user with passport-jwt strategy for authentication on login route. I am not able to register my user and instead, getting back a MissingPasswordError on Postman.

Here is my code

const express = require('express');
const router = express.Router();
const passport = require('passport');
const User = require('../models/user');

router.post('/login', passport.authenticate('jwt', { session: false }), (req, res) => {
    res.header({
        status: '200',
        'Content-Type': 'Application/Json',
    });
    res.json({
        'status': 'ok',
        'message': `You have successfully logged in, ${req.user.username} !`
    })
});

router.post('/register', async (req, res) => {
    const username = req.body.username;
    try {
        // here i am getting an error since password is not going through. 
        const user = await User.register(new User({ username }, req.body.password))
        if (req.body.email) {
            user.email = req.body.email;
        }
        const savedUser = await user.save();
        console.log(savedUser);
        res.json({
            status: 200,
            'Content-Type': 'Application/Json',
            'message': `You have successfully regirstered yourself, ${savedUser.username}!`
        })
    } catch (err) {
        err.statusCode = 500;
        res.header({
            status: '200',
            'Content-Type': 'Application/Json',
        });
        res.json({ err });
    }
});

module.exports = router;

I am also trying to use async/await instead of callbacks. The original syntax of register method is :-

User.register({username:'username'}, 'password', function(err, user) {
   ...
});

I have a few questions :-

  • What's causing this problem ?
  • Is my way of using async\await incorrect ? What's the correct way to use `async\wait' here ?
  • Is it incorrect to passport-local-mongoose's register method to register my User while I'm using passport-jwt strategy for authentication ?
  • What's the correct way of solving this problem ?
1 Answers

I found a solution to this problem. I don't clearly understand why but I think the problem lies with using register method since the register method is provided by passport-local-mongoose which actually uses and implements a passport-local strategy internally.

Meanwhile, the strategy being used here is passport-jwt. I browsed the internet to gather info on how to register a new user when implementing passport-jwt strategy. Below is the solution that I got and what actually worked for me :-

  1. First we will uninstall some unwanted packages and install some new ones.

    npm uninstall passport-local passport-local-mongoose
    npm i bcryptjs
    

NOTE: The first command is not necessary but I wanted to get rid of unwanted packages.

  1. Use bcryptjs to manually generate salt and a hash and then store them to database. You can learn more about bcryptjs from its documentation. bcryptjs

    const bcrypt = require('bryptjs');
    

Then inside the /register route,

router.post('/register', async (req, res) => {
    try {
        const salt = await bcrypt.genSalt(10);
        const password = await bcrypt.hash(req.body.password, salt);
        const user;
        user.username = req.body.username;
        user.password = password;
        if (req.body.email) {
            user.email = req.body.email;
        }
        const savedUser = await user.save();
        console.log(savedUser);
        res.json({
            status: 200,
            'Content-Type': 'Application/Json',
            'message': `You have successfully regirstered yourself, ${savedUser.username}!`
        })
    } catch (err) {
        err.statusCode = 500;
        res.header({
            status: '200',
            'Content-Type': 'Application/Json',
        });
        res.json({ err });
    }
});

NOTE: The original documentation brcypt uses callbacks but I have implemented using async/await.Install latest version to avoid any errors.

Related