Reputation: 403
I am trying to authenticate my user with specific flow.
User will enter email for signup and user will be logged in immediately to the account and I will send email confirmation link, with that link user could update password and login to the account.
But i am stuck
I am confused how to signup and login with email only
route.js
app.post('/get_started', (req, res) => {
let {email} = req.body;
let isEmail = emailValidator(email);
// i will save the user email and try to login
if(isEmail){
passport.authenticate('local',{ successRedirect: '/dashboard', failureRedirect: '/' })
}
})
Startegy.js
import LocalStrategy from 'passport-local'
export default passport => {
passport.use('local',new LocalStrategy( (email, done) => {
console.log(email,'Inside Passport')
}));
}
Upvotes: 4
Views: 2261
Reputation: 3543
Before I demonstrate how to achieve what you have ask for, I would strongly suggest against re-engineering the login and signup systems.These systems have been around since forever and for the most cases, it is best to stick to the traditional ways of doing so.
With that said,
To achieve the functionality that user can login using just email, you can use the passport-custom module which will let you write your own logic to login user.
Register the strategy:
passport.use(
"my-custom-strategy",
new CustomStrategy(function(req, callback) {
const email = req.body.email;
User.exists(email).then(exists => {
const info = {};
if (exists) {
// user has already entered password,
// redirect to some page and where user can enter the password
info.passwordRequired = true;
} else {
// user has not entered password,
// add the user to db
// send the link and let them login for now
info.sendEmailLink = true;
}
return callback(null, { email }, info);
});
callback(null, user);
})
);
I assume that User.exists(email)
method is available which will return the promise that will
either resolve to true
or false
based based of whether the email exists.
The info
object will be used in the controller to implement the actual logic.
app.use("/get_started", (req, res, next) => {
let { email } = req.body;
let isEmail = emailValidator(email);
// i will save the user email and try to login
if (isEmail) {
passport.authenticate("my-custom-strategy", (err, user, info) => {
if (info.passwordRequired) {
// you can use custom cookie to set the user.email
// and access it later to fully authenticate the user
// using the email and password
res.redirect("/enter_password");
} else if (info.sendEmailLink) {
// logic to send the email
// once the email sent, redirect to dashboard
res.redirect("/dashboard");
}
})(req, res, next);
}
});
Upvotes: 1
Reputation: 1198
Here is an example which additionaly uses sequelize and bcrypt:
route.js:
app.post('/get_started', passport.authenticate('local'), (req, res) => {
// Do stuff after successful login here
}
Strategy.js:
passport.use(
'local',
new LocalStrategy(
{usernameField: 'email'},
(email, passwordCleartext, done) =>
User.findOne({where: {email: email}})
.then(user =>
!user ?
done('Unauthorized', false, {message: 'Incorrect email or password.'}) :
bcrypt.compare(passwordCleartext, user.password)
.then(res =>
res ?
done(null, user, {message: 'Logged In Successfully'}) :
done('Unauthorized', false, {message: 'Incorrect email or password.'}))
)
.catch(() => done('Unauthorized', false, {message: 'Incorrect email or password.'}))
)
);
Upvotes: 1