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('/');
});
Related
app.post('/login', checkNotAuthenticated, passport.authenticate('local', {
failureFlash: true
});
I am trying to find a way that when I do a POST request to /login, to get back a JSON like this without any kind of redirect:
{"success": true/false, "message": "Message of what went wrong, e.g.: Password incorrect"}
The passport code:
function initialize(passport, getUserByEmail, getUserById) {
const authenticateUser = async (email, password, done) => {
const user = getUserByEmail(email);
if (user == null) {
return done(null, false, {message: 'No user with that email'});
}
try {
if (await bcrypt.compare(password, user.password)) {
return done(null, user);
} else {
return done(null, false, {message: 'Password incorrect'});
}
} catch (e) {
return done(e);
}
};
passport.use(new LocalStrategy({
usernameField: 'email'
}, authenticateUser));
passport.serializeUser((user, done) => done(null, user.id));
passport.deserializeUser((id, done) => {
return done(null, getUserById(id))
});
}
The login works fine, I just don't know how to send that response, as I am not able to send anything inside the passport function. I tried adding a new function like this:
app.post('/login', checkNotAuthenticated, passport.authenticate('local', {
failureFlash: true
}, (req, res, msg) => {
console.log(req);
console.log(res);
console.log(msg);
}));
But this function is what I send in the previous passport function through "done". So I can get the message from there to send, but I don't have the same "res" containing the res.send method.
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' 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) {
// ...
}
));
I have an Express app with the passport-local strategy, using Mongoose for storing user Accounts. I had a freelancer write this part of the app for me because I couldn't make sense of how to build the login system from beginning to end (every single tutorial I found did it in a different way). The drawback of this is that I don't understand what each part does. This is in my app.js file:
const Account = require('./models/db/AccountsSchema');
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(Account.authenticate()));
passport.serializeUser(Account.serializeUser());
passport.deserializeUser(Account.deserializeUser());
and this is in routes/index.js:
router.post('/register', function(req, res) {
Account.register(new Account({
username: req.body.username,
name: req.body.name
}), req.body.password, function(err, account) {
if (err) {
console.log(err);
} else {
console.log(account);
passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/login'
})(req, res, function(err, user) {
res.redirect('/');
});
}
});
});
along with:
router.post('/login',
passport.authenticate('local'),
function(req, res) {
res.redirect('/');
}
);
Now in the login POST request I want to have a check for whether a user with that particular username exists, so that if the password is wrong at least I can tell the user that the password is wrong. User enumeration is not a security concern here.
Where in my code can I incorporate a database check for whether an Account with the specified username exists?
In Account.authenticate() function. As it sets the LocalStrategy in your case.
setting your local strategy:
passport.use(new LocalStrategy(Account.authenticate()));
Sample Code:
function authenticate(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);
});
}
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.