Express/Passport creating session but not sending cookie to front end - node.js

right now I have a react and node.js project running.
Client side(react app) - http://localhost:3000
Server side(Node.js) - http:..localhost:5000
I am currently trying to implement the user authentication session. So far, it will send the username, password, and email(when registering) to the server. The server will then parse the data and attempt to register/login the user. The user credential is stored in an MongoDB atlas database. If it is successful, it will send the info back to the server.
After a successful authentication, the server is supposed to create a session and cookie pair. The session will be stored and the cookie will be sent to the client. However, the latter part isn't happening. I know the session is being created successfully as it is stored in another database in the MongoDB, but no matter what I do, I can't seem to get the cookie to the front end.
UserModel
const mongoose = require('mongoose');
const uniqueValidator = require('mongoose-unique-validator');
const passportLocalMongoose = require('passport-local-mongoose');
const bcrypt = require('bcrypt');
const SALT_WORK_FACTOR = 10;
const userSchema = new mongoose.Schema({
username:{
type: String,
lowercase:true,
unique: true,
required:[true, 'Username is required'],
match:[/^[a-zA-Z0-9]+$/, 'is an invalid username'],
index: true
},
password:{
type: String,
required:[true, 'Password is required']
},
email:{
type:String,
lowercase:true,
unique:true,
required:[true, 'Email is required'],
match:[/\S+#\S+\.\S+/, 'is an invalid email'],
index: true,
uniqueCaseInsensitive: true
}
}, {timestap: true})
userSchema.plugin(uniqueValidator, {message: '{PATH} is already taken.'});
//encrypt the password
userSchema.pre('save', function(next) {
var user = this;
// only hash the password if it has been modified (or is new)
if (!user.isModified('password')) return next();
// generate a salt
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
if (err) return next(err);
// hash the password using our new salt
bcrypt.hash(user.password, salt, function(err, hash) {
if (err) return next(err);
// override the cleartext password with the hashed one
console.log("hashedPassword stored");
user.password = hash;
next();
});
});
});
//validatePassword
userSchema.methods.comparePassword = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
if (err) return cb(err);
cb(null, isMatch);
});
};
userSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model('users', userSchema, 'userInfo');
authRouter.js
router.post("/register-login",
//this section checks the authentication
(req, res, next) =>{
passport.authenticate('local'
,
{ successRedirect: '/',
failureRedirect: '/listingsForm'
}
,
//this will be called if authenticate was successful
(err, user, info) => {
if(req.body.isSignUp){
if(err){
return res.status(400).json({errors:err});
}
if(!user){
return res.status(400).json({errors:info});
}
else{
return res.status(200).json({success: `created ${user.username}`});
}
}
else{
if(err){
return res.status(400).json({errors:err});
}
if(!user){
return res.status(400).json({errors:info});
}
else{
console.log(user.id);
req.login(user, (err)=>{
if(err){
throw err;
}
});
return res.status(200).json({success:`Welcome back ${user.username}`});
}
}
})(req,res,next)
}
authUser.js
const User = require('../schemes/User')
const passport = require('passport');
const LocalStrategy = require('passport-local');
passport.serializeUser((user,done) =>{
console.log(user.id);
done(null,user.id);
})
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user);
});
});
passport.use(
new LocalStrategy(
{
usernameField: 'username',
passwordField: 'password',
passReqToCallback: true
},
(req, username, password, done) =>{
// console.log(username, password);
console.log(req.body);
//For Register
if(req.body.isSignUp){
//determine it is a register attempt
const newUser = new User({
username: username,
password: password,
email: req.body.email
});
newUser.save()
.then(
user => {
return done(null,user);
}
)
.catch(
err => {
console.log('there is error');
console.log(err);
return done(null, false, {message:err.message});
}
)
}
//For Login
else{
User.findOne({username: username})
.then(user => {
let attemptPassword = password;
if(!user){
return done(null, false, {message:'This username/password does not exist'})
}
else{
console.log("will verify now");
user.comparePassword(attemptPassword, function(err, isMatch) {
if (err){
console.log('hihi');
return done(null, false, {message:err})
}
if(!isMatch){
return done(null, false, {message:'This username/password does not exist'})
}
return done(null, user), {message:'Successfully Logged In'};
});
}
})
}
}
));
module.exports = passport;
Index.js
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
//expression session
app.use(session({
secret: 'secret',
resave: false,
saveUninitialized: true,
store: new MongoStore({mongooseConnection:mongoose.connection})
}))
app.use(passport.initialize());
app.use(passport.session());
//express-router
const authRouter = require('./routes/auth-router');
app.use('/users',authRouter);
server.listen(PORT, () => console.log(`Server has started on port ${PORT}`));

I guess app.use(cors({credentials:true})); will solve your problem, gyus.

Related

How can I add the feature of 'Change Password' in nodejs with passport authentication and passport-local package?

This is the authentication passport code I have put it in passport.js:
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
passport.serializeUser(function (user, done) {
done(null, user._id);
});
passport.deserializeUser(function (id, done) {
User.findOne({_id: id}, function (err, user) {
done(err, user);
})
});
passport.use(new LocalStrategy({
usernameField: 'email'
},
function (username, password, done) {
User.findOne({email: username}, function (err, user) {
if (err) return done(err);
if (!user) {
return done(null, false, {
message: 'Incorrect username or password'
});
}
if (!user.validPassword(password)) {
return done(null, false, {
message: 'Incorrect username or password'
});
}
return done(null, user);
})
}
));
And this is the Schema code I am storing password in the form of salt and hash in mongoDB using mongoose queries:
var mongoose = require('mongoose');
var crypto = require('crypto');
var userSchema = new mongoose.Schema({
email: {
type: String,
unique: true,
required: true
},
name: {
type: String,
required: true
},
hash: String,
salt: String
});
userSchema.methods.setPassword = function(password) {
this.salt = crypto.randomBytes(16).toString('hex');
this.hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha1').toString('hex');
};
userSchema.methods.validPassword = function(password) {
var hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha1').toString('hex');
return this.hash === hash;
};
module.exports = mongoose.model('User', userSchema);
This is the auth.js code for Login route:
var express = require('express');
var router = express.Router();
var passport = require('passport');
var mkdirp = require('mkdirp');
var nodemailer = require('nodemailer');
var config = require('../config');
var transporter = nodemailer.createTransport(config.mailer);
router.route('/login')
.get(function(req, res, next) {
res.render('login', { title: 'Login your account'});
})
.post(passport.authenticate('local', {
failureRedirect: '/login'
}), function (req, res) {
res.redirect('/profile');
})
And below is the password change route I am trying to execute which is possibly not working. What I think is I need to update the hash and salt value into the database while user changes password successfully which I am unable to figure out how can I do it. Please help!!!!!!!!!!!!!!!
router.post('/api/changePassword', function(req,res,next){
req.checkBody('oldPass', 'Empty Password').notEmpty();
req.checkBody('newPass', 'Password do not match').equals(req.body.confirmPass).notEmpty();
var errors = req.validationErrors();
if (errors) {
console.log("Errors hain bhai");
console.log(errors);
res.render('settingsClient', {
oldPass: req.body.oldPass,
newPass: req.body.newPass,
confirmPass:req.body.confirmPass,
errorMessages: errors
});
}
else {
User.findOne({id: req.user.id}, function (err, data) {
console.log("came inside api changePassword else condition inside User.findOne");
if (err) {
console.log(err);
}
else {
data.setPassword(req.body.newPass, function(err,datas){
if(datas) {
data.save(function (err,datass) {
if (err) {
res.render('settingsClient', {errorMessages: err});
} else {
console.log("Hash and Salt saved");
}
});
}
else {
console.log("setPassword error"+ err);
}
});
}
})
}
})
Its not working/not updating the password values into the database. What could be the possible reason and mistake I might be doing?
Yeah! So I removed the callback funtion from the setPassword and tried with the promises way/route to solve this query:
Here I am posting the solution which is working fine now.
User.findOne(userObj).then(function(sanitizedUser) {
if (sanitizedUser) {
console.log("sanitizedUser.hash = "+ sanitizedUser.hash);
sanitizedUser.setPassword(req.body.newPass);
console.log("Password going to be changed successfully now")
sanitizedUser.save(function (err,data) {
if (err) {
res.render('register', {errorMessages: err});
} else {
console.log("Password changed successfully");
res.send('Password reset successful');
}
});
} else {
res.send('user does not exist');
}
}, function(err) {
console.error(err);
});

Is there a way of defining what collection to use when using passport.authenticate

Within my project I have both hcpuser and regular user. I have got the registration working for HCP but when i go to do my login function it still only reads from my users collection and not from the hcpuser I want it to. Is there a simple line of code I can declare before my function that allows this.
Hcp model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var bcrypt = require('bcryptjs');
var User = require('../model/user.model').schema
var schema = new Schema({
email : {type:String, require:true},
username: {type:String, require:true},
password:{type:String, require:true},
creation_dt:{type:Date, require:true},
hcp : {type:Boolean, require : true},
clinic:{type:String, require:true},
patients: [User],
});
schema.statics.hashPassword = function hashPassword(password){
return bcrypt.hashSync(password,10);
}
schema.methods.isValid = function(hashedpassword){
return bcrypt.compareSync(hashedpassword, this.password);
}
schema.set('collection', 'hcpuser');
module.exports = mongoose.model('Hcpuser',schema);
Hcp controller with first register function working as expected.
const express = require("express");
const mongoose = require("mongoose");
const cors = require("cors");
const router = express.Router();
const Hcpusermodel = mongoose.model("Hcpuser")
const {ObjectId} = require("mongodb");
var Hcpuser = require('../model/hcp.model')
var passport = require('passport');
router.post('/register', function (req, res, next) {
addToDB(req, res);
});
async function addToDB(req, res) {
var hcpuser = new Hcpuser({
email: req.body.email,
hcp : true,
username: req.body.username,
password: Hcpuser.hashPassword(req.body.password),
clinic: req.body.clinic,
creation_dt: Date.now()
});
try {
doc = await hcpuser.save();
return res.status(201).json(doc);
}
catch (err) {
return res.status(501).json(err);
}
}
//login
router.post('/login', function(req,res,next){
passport.authenticate('local', function(err, hcpuser, info) {
if (err) { return res.status(501).json(err); }
if (!hcpuser) { return res.status(501).json(info); }
req.logIn(hcpuser, function(err) {
if (err) { return res.status(501).json(err); }
return res.status(200).json({message:'Login Success'});
});
})(req, res, next);
});
From your question, you either want to auth one OR the other, or check both - I think you're asking for how to auth separately (one OR the other, not both)?
please note, this specific code has been untested, but the principles are there and still stand.
One OR the Other
You need to define the name of each strategy in your passport code.
For example:
passport.use('users', new LocalStrategy({
usernameField: 'user[email]',
passwordField: 'user[password]',
},(email, password, done) => {
Users.findOne({ email })
.then((user) => {
if(!user || !user.validatePassword(password)) {
return done(null, false, { errors: { 'email or password' : 'is valid' } });
}
return done(null, user);
}).catch(done);
}));
passport.use('hcpusers', new LocalStrategy({
usernameField: 'user[email]',
passwordField: 'user[password]',
},(email, password, done) => {
HCPUser.findOne({ email })
.then((user) => {
if(!user || !user.validatePassword(password)) {
return done(null, false, { errors: { 'email or password' : 'is valid' } });
}
return done(null, user);
}).catch(done);
}));
And then in your passport.authenticate method, specify the strategy name:
passport.authenticate('users', function(err, user, info) { ...
and
passport.authenticate('hcpusers', function(err, user, info) { ...
In this case you'll need two separate endpoints for each login method, or just an extra parameter specifying which one to check from an if statement.
Update
For your comment of not knowing where the passport code should be, this is up to you. However, I like to keep passport code in an 'auth' folder and add the following code to a passport.js file:
const mongose = require('mongoose');
const passport = require('passport');
const LocalStrategy = require('passport-local');
const Users = mongose.model('Users');
passport.use('...', new LocalStrategy({
...
...
}));
Include this in your server/index/app.js (whatever yours is) app.use(passport.initialize());
You can then just use the passport code as normal in your user controllers.
My passport.authenticate code looks like:
return passport.authenticate('local', function(err, passUser, info) {
if (err) {
return next(err);
}
if (!passUser) {
return res.status(503).send('error');
}
const user = passUser;
user.token = user.generateJWT();
return res.json({ token: user.token });
})(req, res, next);
But this can be different for you (i.e. you may not be using sessions?) Either way, if authenticated, just send the response to client so it can proceed.
Hi so to solve this issue i followed what was mentioned. I needed to define the name of the collection within the hcp model using this:
module.exports = mongoose.model('Hcpuser', Hcpuser, 'Hcpuser');
I then created a local strategy ensuring that i was searching using the right model which would then point to the right collection within my DB.
Solution:
var passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
passport.use('hcplocal', new LocalStrategy(
function(uemail, password, done) {
Hcpuser.findOne({ "email" : uemail }, function(err, user) { console.log(user)
if (err) { return done(err); }
if (!user) {
console.log(user);
console.log(err);
console.log(uemail)
return done(null, false, { message: 'Incorrect email.' });
}
if (!user.isValid(password)) {
console.log(user);
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
router.post('/login',function(req,res,next){
passport.authenticate('hcplocal', function(err, user, info) {
if (err) { return res.status(501).json(err); }
if (!user) { return res.status(501).json(info); }
req.logIn(user, function(err) {
if (err) { return res.status(501).json(err); }
console.log(user);
return res.status(200).json({message:'Login Success'});
});
})(req, res, next);
});

TypeError: User.comparePassword is not a function, can't login or register users

I am attempting to compare password that the user registers with and then logins with and get the following error:
TypeError: User.comparePassword is not a function
at /home/ubuntu/workspace/app.js:51:10
at Query.<anonymous> (/home/ubuntu/workspace/node_modules/mongoose/lib/model.js:4038:16)
at /home/ubuntu/workspace/node_modules/kareem/index.js:273:21
at /home/ubuntu/workspace/node_modules/kareem/index.js:131:16
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickCallback (internal/process/next_tick.js:104:9)
User model where comparePassword() located
var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");
var bcrypt = require("bcrypt-nodejs");
var UserSchema = new mongoose.Schema({
username: {type: String, unique: true, required: true},
password: {type: String, unique: true, required: true},
// avatar: String,
firstName: String,
lastName: String,
email: {type: String, unique: true, required: true},
resetPasswordToken: String,
resetPasswordExpires: Date,
// isAdmin: {type: Boolean, default: false}
});
UserSchema.plugin(passportLocalMongoose);
//save function -- hashes and then saves the password
UserSchema.pre('save', function(next) {
var user = this;
var SALT_FACTOR = 5;
if (!user.isModified('password')) return next();
bcrypt.genSalt(SALT_FACTOR, function(err, salt) {
if (err) return next(err);
bcrypt.hash(user.password, salt, null, function(err, hash) {
if (err) return next(err);
user.password = hash;
next();
});
});
});
//compares and checks password
UserSchema.methods.comparePassword = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
if (err) return cb(err);
cb(null, isMatch);
});
};
module.exports = mongoose.model("User", UserSchema);
Here is the app.js file it gets passed to:
var express = require("express"),
app = express(),
bodyParser = require("body-parser"),
mongoose = require("mongoose"),
expressSanitizer = require("express-sanitizer"),
passport = require("passport"),
cookieParser = require("cookie-parser"),
LocalStrategy = require("passport-local"),
session = require("express-session"),
nodemailer = require("nodemailer"),
bcrypt = require("bcrypt-nodejs"),
async = require("async"),
crypto = require("crypto"),
flash = require("connect-flash"),
moment = require("moment"),
User = require("./models/user"),
// seedDB = require("./seeds"),
methodOverride = require("method-override");
// APP CONFIG
mongoose.connect("mongodb://localhost/blog", {useMongoClient: true});
//PRODUCTION CONFIG - LIVE URL GOES HERE!
app.set("view engine", "ejs");
app.use(express.static(__dirname + "/assets"));
app.use(bodyParser.urlencoded({extended: true}));
app.use(expressSanitizer());
app.use(methodOverride("_method"));
app.use(cookieParser('secret'));
//require moment
app.locals.moment = require('moment');
// seedDB(); //seed test data!
// PASSPORT CONFIGURATION
app.use(require("express-session")({
secret: "It's a secret to everyone!!",
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
passport.use(new LocalStrategy(function(username, password, done) {
User.findOne({ username: username }, function(err, user) {
if (err) return done(err);
if (!user) return done(null, false, { message: 'Incorrect username.' });
console.log(user);
User.comparePassword(password, function(err, isMatch) {
if (isMatch) {
return done(null, user);
} else {
return done(null, false, { message: 'Incorrect password.' });
}
});
});
}));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
app.use(function(req, res, next){
res.locals.currentUser = req.user;
res.locals.success = req.flash('success');
res.locals.error = req.flash('error');
next();
});
Whenever I register or try to sign in I get the comparePassword is not a function error.
here is my mongo db of one of the examples of a user called "apple"
{ "_id" : ObjectId("5a2ec9ff5e64680bdd930330"), "salt" : "398d81d059440847480ae8f31c20c3e21c3a1b522ba57dbeed6f8cfa9fddf1b7", "hash" : "3270b089ac910853e07c40bdb1e71a948ccfee378b9d92936a50f53f6f4e02f79bdb6cc611c0e15a5c8dbdded8c165b30c86597ce202d47af89859ef074f093ecc4bfe9419fe406ee067ba60fdc97acda4934ae95160b29a9e6fa57b288ddad7c4fe84e459d165256084c8af9399d0258f93d24068e03e0b5cef704c3c115b78944c98b8c431bdb3d6314803f30af318f135316277050f71897f0009e1509da0634fe1bbf6c80bfb66a9d175061544e28d33f7573780e7be576db409b8950fb79d63b40aa34bea8919bf81afd46bddd866e1eab4fa447ba26af137f4bf01559b6632084b9d04677671f85b9b5ec4fe4eaf088c1023fb512a93e546dcab1571ec02217594cba2894a5468f41b4935f976d79587d47f16bb4ef00566ded4a0b349cda6f442fd5b11e325e1feb651d3c367b5943d22ed32e6ec14065bea58cb6fbd55bf13daab2b183bb6ab59f150a64b99304ce7b163621753d69377cc394c8d5ec9c2e30ef6ab50f32e8241c542a01950d3e16c1d83aa6986a67aac96e9652270919bd05e6994493b89326857bf9ac75a450a39ba79f2af0035354e40bd32c43f9acc7e660158ca17e3d7e66673ab8950a63126fa0f6f7206de71bef0c3f212022b5f6eaee49775c2750e8ac068b98566bf6fe643c935e6dac531b9a5b12ace19c850ec369f431432b7a2d0817097f3762244ee8db1f30c0814bcbcaf8b6ab77c", "username" : "apple", "firstName" : "apple", "email" : "apple#gmail.com", "password" : "$2a$05$lkr5htZwOBVSIMJSQXveduEKmx6/AnN7jUxTjDSDKr3UQ0DqaQzrS", "__v" : 0 }
>
Try using lower case user:
user.comparePassword(password, function(err, isMatch) {
if (isMatch) {
return done(null, user);
} else {
return done(null, false, { message: 'Incorrect password.' });
}
});

Node JS Authentications with passport-jwt unauthorized

Im trying to setup my Node JS API.
I have a User model :
// Dependencies
var restful = require('node-restful');
var mongoose = restful.mongoose;
var bcrypt = require('bcrypt');
// Schema
var userSchema = new mongoose.Schema({
username: {
type: String,
required: true,
unique: true},
firstname: {
type: String,
required: true
},
lastname: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true,
lowercase: true
},
password: {
type: String,
required: true},
},
{
timestamps: true
});
// Saves the user's password hashed
userSchema.pre('save', function (next) {
var user = this;
if (this.isModified('password') || this.isNew) {
bcrypt.genSalt(10, function (err, salt) {
if (err) {
return next(err);
}
bcrypt.hash(user.password, salt, function(err, hash) {
if (err) {
return next(err);
}
user.password = hash;
next();
});
});
} else {
return next();
}
});
// Use bcrypt to compare passwords
userSchema.methods.comparePassword = function(pw, cb) {
bcrypt.compare(pw, this.password, function(err, isMatch) {
if (err) {
return cb(err);
}
cb(null, isMatch);
});
};
module.exports = restful.model('Users', userSchema);
I want to use passport with jwt for authentication :
// Dependencies
var JwtStrategy = require('passport-jwt').Strategy;
var ExtractJwt = require('passport-jwt').ExtractJwt;
var config = require('../config/database');
// Load models
var User = require('../models/user');
// Logique d'authentification JWT
module.exports = function(passport) {
var opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('JWT');
opts.secretOrKey = config.secret;
opts.audience = 'localhost';
passport.use(new JwtStrategy(opts, function(jwt_payload, done) {
User.findById(jwt_payload._id, function(err, user) {
if (err) {
return done(err, false);
}
if (user) {
done(null, user);
} else {
done(null, false);
}
});
}));
passport.use(new JwtStrategy(opts, function(jwt_payload, done) {
Company.findById(jwt_payload._id, function(err, company) {
if (err) {
return done(err, false);
}
if (company) {
done(null, company);
} else {
done(null, false)
}
});
}));
};
And my route for authentication :
// User
router.post('/users/login', (req, res) => {
User.findOne({
email: req.body.email
}, (err, user) => {
if (err) throw err;
if (!user) {
res.json({success: false, message: 'Authentication failed. User not found.'});
} else {
// Check if passwords matches
user.comparePassword(req.body.password, (err, isMatch) => {
if (isMatch && !err) {
// Create token if the password matched and no error was thrown
var token = jwt.sign(user, config.secret, {
expiresIn: 10080 // in seconds
});
res.json({success: true, token: 'JWT ' + token, user: {
id: user._id,
username: user.username,
email: user.email
}});
} else {
res.json({success: false, message: 'Authentication failed. Passwords did not match.'});
}
});
}
});
});
Everything work great on postman.
The token is correctly generated and signed with user's informations.
But i have a problem with the authentication on a protected route :
router.get('/users/profile', passport.authenticate('jwt', { session: false }), function(req, res) {
res.send('It worked! User id is: ' + req.user._id + '.');
});
Everytime, it gives me an "Unauthorized 401" Error.
I really dont know where is the problem, i think the problem is around jwtFromRequest, i also tried with Bearer but it also doesn't work...
I think a good option to avoid this kind of problems is to start from a base project that uses this authentication strategy, and after you have that working, modify it with your functionality.
Here you have an example with jwt authentication strategy and Refresh token implementation: https://solidgeargroup.com/refresh-token-autenticacion-jwt-implementacion-nodejs?lang=es

Passport in node.js

Ok, I edit the question, Can someone help me with fix this code, to work??
I am fallow the guide with youtube about creating login system with using passport, I dont understand here about function
passport.use(new LocalStrategy(
When is she called, And from where it gets an argument login, password.
USER MODEL
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
login: { type: String, maxlength: 20, required: false },
password: { type: String, maxlength: 202, required: false },
updated: { type: Date, default: Date.now },
created: { type: Date, default: Date.now }
});
module.exports = mongoose.model('User', UserSchema);
module.exports.comparePassword = function(candidatePassword, hash, callback){
bcrypt.compare(candidatePassword, hash, function(err, isMatch) {
if(err) throw err;
callback(null, isMatch);
});
}
module.exports.getUserById = function(id, callback){
User.findById(id, callback);
}
User Model
var express = require('express');
var MongoClient = require('mongodb').MongoClient;
var router = express.Router();
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var Product = require('../../model/product.model');
var Category = require('../../model/category.model');
var mongoose = require('mongoose');
var User = require('../../model/user.model');
var _ = require('lodash');
var bcrypt = require('bcrypt');
const saltRounds = 10;
router.post('/create', function (req, res, next) {
var newUser = {
login: req.body.login,
password: req.body.password
}
console.log(req.body)
req.checkBody('login', 'Login is required').notEmpty();
req.checkBody('password', 'Password is required').notEmpty();
var errors = req.validationErrors();
if (errors) {
console.log(errors)
res.send(errors);
} else {
bcrypt.hash(newUser.password, saltRounds, function (err, hash) {
if (err) {
console.log(err)
} else {
newUser.password = hash;
var user = new User(newUser);
user.save()
.then(function (User) {
res.send(User);
})
}
});
req.flash('success_msg', 'You are registered and can now login');
//res.redirect('/');
}
});
passport.use(new LocalStrategy(
function(login, password, done) {
User.findOne({ login: login }, function(err, user){
if(err) {
console.log(err);
}
if(!user) {
return done(null, false, {
message: 'Unkown User'
})
}
});
User.comparePassword(password, user.password, function(err, isMatch){
if(err) throw err;
if(isMatch){
return done(null, user);
} else {
return done(null, false, {message: 'Invalid password'});
}
});
}));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.getUserById(id, function(err, user) {
done(err, user);
});
});
router.post('/login', function (req, res, next) {
console.log(req.body)
passport.authenticate('local', { successRedirect: '/', failureRedirect: '/', failureFlash: true }),
function (req, res) {
res.redirect('/product/list')
}
})
module.exports = router;
When is she called?
passport.use(new LocalStrategy( will be used when you call passport.authenticate('local'..
In your project it is while getting post request with '/login'.
LocalStrategy provides strategy to authenticate requests. You can choose different strategy. Strategies, and their configuration, are supplied via the use() function. More information: Passport Documentation
From where it gets an argument login, password?
By default, LocalStrategy expects to find credentials in parameters named username and password. If your site prefers to name these fields differently, options are available to change the defaults.
From LocalStrategy Documentataion

Resources