Register User Through Passport Js

Viewed 18830

i want to add new user from signup page through help of passport.js Signup form is following

<form id="Signup-form" name="SignupForm" action="/signup" method="post"/>
<input type="text" id="firstname" name="Firstname" >
<input type="text" id="lastname" name="Lastname"/>
<input type="email" name="email" />
<input type="text" id="rollno" name="rollno"/>
<input type="password" name="password" id="password"/>
<input type="password" name="confirm" id="confirm-password"/>
<input type="radio" name='Gender' value="Male" />
<input type="radio" name='Gender' value="FeMale" />
</form>

my passport is initialized in app.js as

required

var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;

after db setting

require('./config/passport');

intialized as

app.use(passport.initialize());
app.use(passport.session());

post sign up route

router.post('/signup', passport.authenticate('local.signup' , {
successRedirect : '/home',
failuerRedirect : '/signup',
failuerFlash: true
}));

my user model

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var bcrypt = require('bcrypt-nodejs')

const UserSchema = new Schema({
First_Name : String,
Last_Name : String,
email : String,
Roll_No : String,
Gender : String,
password : String
},{collection : 'Users'});

UserSchema.methods.encryptPassword = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(5), null);
};

UserSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.password);
}
var User = mongoose.model('User' , UserSchema); 
module.exports = User;

now my passport.js file in config dir is

var passport = require('passport');
var User = require('../models/user');
var LocalStrategy = require('passport-local').Strategy;
passport.serializeUser(function (user, done) {
done(null, user.id);
});

passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
done(err, user);
 });
});

my main questions how to write strategy for this route with all fields

passport.use('local.signup', new LocalStrategy({
//strategy code here
}));
4 Answers

Here is a good example Easy Node Authentication: Setup and Local

passport.use('local-signup', new LocalStrategy({
        // by default, local strategy uses username and password, we will override with email
        usernameField : 'email',
        passwordField : 'password',
        passReqToCallback : true // allows us to pass back the entire request to the callback
    },
    function(req, email, password, done) {

        // find a user whose email is the same as the forms email
        // we are checking to see if the user trying to login already exists
        User.findOne({ 'local.email' :  email }, function(err, user) {
            // if there are any errors, return the error
            if (err)
                return done(err);

            // check to see if theres already a user with that email
            if (user) {
                return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
            } else {

                // if there is no user with that email
                // create the user
                var newUser            = new User();

                // set the user's local credentials
                newUser.local.email    = email;
                newUser.local.password = newUser.generateHash(password);

                // save the user
                newUser.save(function(err) {
                    if (err)
                        throw err;
                    return done(null, newUser);
                });
            }

    }));

For anyone trying to figure out how to add additional fields to passport-local besides username (which can be email) and password, the accepted answer only hints at how to do it. Let's say you want to use name, email, and password for your user model. You can do it with Passport-local like this:

const passport = require('passport');
const localStrategy = require('passport-local').Strategy;
const User = require('./model/user');

passport.use('signup', new localStrategy({
  usernameField : 'email',
  passwordField : 'password',
  passReqToCallback: true
}, async (req, email, password, done) => {
  try {
    const name = req.body.name;
    const user = await User.create({ name, email, password });
    return done(null, user);
  } catch (error) {
    done(error);
  }
}));

The things to note are: The passport localStrategy object does not accept other fields besides usernameField and passwordField. But you can pass the request object to the callback. Then, before saving the user to the database, pull the fields out of the req.body object and put them in the create method (if you are using Mongoose.js).

Passportjs also have utility functions. If you don't want to use middleware to register user, you can use regular post request which will create user and then use login function from passport js to authenticate it (add newly created user object to the current session)

router.post('/auth/signup',(req,res,next) => {
  const user = new User();
  
  req.login(user,(err) => {
    console.log("success");
  }
})

see this link for more details http://www.passportjs.org/docs/login

Related