I' learning Node.s and Express, and I'm following this example from https://github.com/EvanHahn/Express.js-in-Action-code/tree/master/Chapter_08/learn-about-me. Can you explain the following question?
In the "/login" post route, if I need to access the request and response objects, how should I do it?
What is the "done" function inside LocalStrategy(), and how I know what parameter to pass? Looks like it take 3 arguments, and the 2nd argument is the user object, and the 3rd argument is the message. What is the 1st argument?
How do the username and password get passed from the "/login" post route into LocalStrategy? What magic is behind the scene?
router.post("/login", passport.authenticate("login", {
successRedirect: "/",
failureRedirect: "/login",
failureFlash: true
}));
passport.use("login", 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: "No user has that username!" });
}
user.checkPassword(password, function(err, isMatch) {
if (err) { return done(err); }
if (isMatch) {
return done(null, user);
} else {
return done(null, false, { message: "Invalid password." });
}
});
});
}));
The answer for question #1 and #2 is at http://passportjs.org/docs
app.get('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.redirect('/login'); }
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.redirect('/users/' + user.username);
});
})(req, res, next);
});
3 is at the same docs page.
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'passwd'
},
function(username, password, done) {
// ...
}
));
Related
I have made a user register and login but I couldnt understand why req.user shows undefined.
I couldnt understand why it shows undefined.
I have middleware of :
app.use(passport.initialize());
app.use(passport.session());
And also I have middleware of body-parser
This is my register(post):
app.post('/register',[
// username must be an email
check('kullanici_adi').notEmpty(),
// email must be at least 5 chars long
check('email').isEmail(),
// email must be at least 5 chars long
check('sifre').notEmpty(),
], async (req, res) => {
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(req.body.sifre, salt);
let kullanici = new Kullanici({
kullanici_adi: req.body.kullanici_adi,
email: req.body.email,
sifre: hashedPassword,
});
const errors = validationResult(req);
if (!errors.isEmpty()) {
req.flash('danger', 'Bütün Alanların Doldurulması Zorunludur');
res.render('kayit', {
});
}
kullanici.save(function(err) {
if (err) {
console.log(err);
} else {
res.redirect('/');
}
});
});
This is my login parts:
app.get('/login', function(req, res){
res.render('login');
});
app.post('/login', (req, res, next) => {
passport.authenticate('local', {
failureRedirect: '/login',
successRedirect: '/',
failureFlash: true,
}) (req, res, next);
});
app.get('/logout', function(req, res){
req.logout();
req.flash('success', 'You are logged out');
res.redirect('/login');
});
And this is passportjs configure part:
passport.use(new LocalStrategy({
usernameField: 'kullanici_adi',
passwordField: 'sifre'
},
function(username, password, done) {
Kullanici.findOne({ kullanici_adi: username }, function (err, kullanici) {
if (err) { return done(err); }
if (!kullanici) {
return done(null, false, { message: 'Incorrect username.' });
}
bcrypt.compare(password, kullanici.sifre, function(err, isMatch){
if(err) throw err;
if(isMatch){
return done(null, kullanici);
} else {
return done(null, false, {message: 'Wrong password'});
}
});
});
}
));
passport.serializeUser(function(kullanici, done) { done(null, kullanici.id); });
passport.deserializeUser(function(id, done) { Kullanici.findById(id, function(err, kullanici) { done(err, kullanici); }); });
When I console.log(req.kullanici) in my index or post routes then it says undefined. But at the same time this undefined user can pass through ensureAuthenticated parts of my website.
Note: Some words meaning in English:
Kullanici = User,
kullanici = user,
kullanici_adi = username,
sifre = password,
email = email,
Can someone help met? Why it is being happened and how to solve this issue?
Full code:https://github.com/michelson/dante2/issues/229
I am building app using MEAN STACK. I want to use passport-local authentication for my login form. But a the time of form submission i am getting POST http://localhost/login 404 (Not Found) please have a look of my code below This is my controller:
lyfee.controller('loginCtrl', ['$scope', '$http', function($scope, $http) {
$scope.user = {};
$scope.login = function() {
// var data = {User: $scope.user }
//console.log($scope.user);
console.log("login function call");
$http.post('/login', $scope.user);
console.log("login request send");
}
}]);
and this is my server.js :
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function(username, password, done) {
User.getUserByusername(username, function(err, user) {
if (err) throw err;
if (!user) {
return done(null, false, {
message: 'Unknown USER'
});
}
User.comparePassword(password, user.password, function(err, isMatch) {
if () throw err;
if (isMatch) {
return done(null, user);
} else {
return done(null, false, {
message: 'Invalid password'
});
}
});
});
}));
app.post('/login',
passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/login',
failureFlash: true
}),
function(req, res) {
res.redirect('/');
});
in which file should i write getUserByusername and comparePassword function ? and what is mistake i am doing please correct it and give me some suggestion.
In your model suppose that User.js write functions like this:
/**
* Check the user's password
*/
dbSchema.methods.comparePassword = function(candidatePassword, cb) {
var status = this.password.localeCompare(candidatePassword.trim());
if (status != 0) {
return cb(err);
}
cb(null, true);
};
then use the function like this
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({
username: username
}, function(err, user) {
if (err) throw err;
if (!user) {
return done(null, false, {
message: 'Unknown USER'
});
}
/**
* Check the user's password
*/
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'
});
}
});
});
}));
For a regular authentication, the 'Incorrect password' message is available via failureFlash
app.post('/login',
passport.authenticate('local', { successRedirect: '/',
failureRedirect: '/login',
failureFlash: true })
);
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.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
But if I use a custom callback, how can I access that 'Incorrect password' message and show it to the user ? Because the custom callback only seems to check for (!user). I need custom callback as I am doing login via ajax and I cannot have redirects.
app.get('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.status(401).send({"ok": false}); }
req.logIn(user, function(err) {
if (err) { return next(err); }
return return res.send({"ok": true});
});
})(req, res, next);
});
The message is in the info parameter in your custom callback handler making it very easy to access and send to the user.
On a side not, I wouldn't specify if the username or the password was the cause of the login failure. Using that kind of response it is very easy to test which usernames exist, and then just focus on the password.
I am using passport local for authenticating the application .I understood to perform login
Now i wanted to implement registration for the same
I understood we can provide a name to distinguish both local strategy
but i don't know how to invoke them
Login:
app.post('/login',
passport.authenticate('local', {
successRedirect: '/loginSuccess',
failureRedirect: '/loginFailure',
failureFlash: true
}));
passport.use('login',new LocalStrategy(
function(username, password, done) {
process.nextTick(function () {
});
UserDetails.findOne({'username':username},
function(err, user) {
if (!user) { return done(null, false , { message: 'Incorrect username.' }); }
if (err) { return done(err); }
if (user.password != password) { return done(null, false , { message: 'Incorrect password.' }); }
return done(null, user);
});
}
));
app.post('/register',
passport.authenticate('local', {
successRedirect: '/loginSuccess',
failureRedirect: '/loginFailure',
failureFlash: true
}));
passport.use('register',new LocalStrategy(
function(username, password, done) {
process.nextTick(function () {
});
UserDetails.findOne({'username':username},
function(err, user) {
if (user) { return done(null, false , { message: 'EmailId Already exits' }); }
if (err) { return done(err); }
return done(null, user);
});
}
));
where should i configure login and register to pick up corresponding strategy accordingly i am a new bee please revert if someone not understood my question
Updating as cant put code in comment:
Please go through with this article https://scotch.io/tutorials/easy-node-authentication-setup-and-local
and let us know if you face any issue.
You can define it in your end points ..see below.. here /login is your end point where you will receive your requests and in function do your coding for checking user, etc and send res.json with response to user.
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/');
});
I am using Passport.js with Express - for some reason the req.session.passport.user value is not present, when it should be, as you can see:
here is my passport configuration:
passport.serializeUser(function (user, done) {
console.log(colors.bgRed('serialize user called, user:', user));
done(null, user._id);
});
passport.deserializeUser(function (id, done) {
console.log(colors.bgRed('deserialize user called, user_id:', id));
UserModel.getNewUser().findById(id, function (err, user) {
console.log(colors.bgRed('deserialize find user called, user:', user));
done(err, user);
});
});
passport.use('local', new LocalStrategy(function (username, password, done) {
UserModel.getNewUser().findOne({
username: username
}, function (err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, {
message: 'Incorrect username.'
});
}
if (!user.validPassword(password)) {
return done(null, false, {
message: 'Incorrect password.'
});
}
// req.user = user;
return done(null, user);
});
}));
does anyone know what could be going wrong? My only guess is that I might need to deserialize using the Session object, instead of the user id, but that I believe is incorrect. I do know for a fact that deserializeUser and serializeUser are not being called at all.
It was hard to find an answer for this online, so I think one should go here.
The problem was because instead of using this:
app.post('/login', passport.authenticate('local', { successRedirect: '/',
failureRedirect: '/login' }));
...I decided to use this style of call with Passport:
app.get('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.redirect('/login'); }
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.redirect('/users/' + user.username);
});
})(req, res, next);
});
Originally my code was like so:
passport.authenticate('local', function (err, user, info) {
if (err) {
return next(err);
}
if (!user) {
registerUser(req,res,next);
}
else{
res.locals.loggedInUser = user._doc;
res.json({alreadyRegistered: !justRegistered,msg:user._doc});
}
})(req, res, next);
but then I updated it with req.logIn like so:
passport.authenticate('local', function (err, user, info) {
if (err) {
return next(err);
}
if (!user) {
console.log('no account found, so we will register user as expected...');
registerUser(req,res,next);
}
else{
req.logIn(user, function (err) { //this is crucial
if(err){
return next(err);
}
res.locals.loggedInUser = user._doc;
res.json({alreadyRegistered: !justRegistered,msg:user._doc});
});
}
})(req, res, next);
and now it works - should have followed the docs better. I recommend that Jared Hansson puts in "this is crucial" in the docs where I have just labeled it above. Otherwise, yes I should have followed the docs more closely.