Reputation: 284
Today i'm coming with a brand new problem ! First, I have two important files :
passport.js local signup part
passport.use('local-signup', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true // allows us to pass back the entire request to the callback
},
function(req, res) {
var password = req.body.password;
var email = req.body.email;
var generateHash = function(password) {
return bCrypt.hashSync(password, bCrypt.genSaltSync(8), null);
};
User.find({
where: {
email: email
}
}).then(function(user) {
if (user) {
return res.json('That email is already taken');
} else {
var userPassword = generateHash(password);
var data = {
username: req.body.username,
name: req.body.name,
firstname: req.body.firstname,
email: req.body.email,
location: req.body.location,
type: req.body.type,
password: userPassword
};
db.users.create({
username: data.username,
name: data.name,
firstname: data.firstname,
email: data.email,
location: data.location,
type: data.type,
password: data.password
}).then(newUser => {
return res.json(newUser)
});
}
});
}
));
I'm doing an authentification part. First, I want to create an account and to use passport for it : the signup.
I'm also using Sequelize to manage my datamodels. But when i'm calling this localStrategy with a POST request (with my body all ok in postman) I have this error :
Unhandled rejection TypeError: res.json is not a function on the line return res.json(newUser)
Somebody can help me please? Note that done() is not working because of passReqToCallback (but I need this to get my password and email)
Upvotes: 0
Views: 855
Reputation: 598
you are passing a string in req.json. you need to use req.send for string. Example:
replace this line:
return res.json('That email is already taken');
to
return res.send('That email is already taken');
if you want to sen JSON then use this one.
return res.json({msg:'That email is already taken'});
or use this condition
if (req.xhr) { return res.json({msg:'That email is already taken'}) }
Upvotes: 1
Reputation: 464
You can be a little confused but passport doesn't implement signup methods. It's just authorisation library. So you must handle that use-case on your own.
First of all, create route that will be responsible for sign-up and your checks:
app.post('/signup', (req, res) => {
User.findOne({ $or: [{'local.email': req.body.email},{'local.username': req.body.username}]}, function(err, user){
if(err){
return res.send(err);
}
if(user){
if(user.local.email == req.body.email){
return res.send("This email is already taken.")
}
return res.send("This username is already taken.")
}
else{
var userData = new User();
userData.local.name = req.body.name;
userData.local.email = req.body.email;
userData.local.username = req.body.username;
userData.local.password = req.body.password;
userData.save()
.then(item => {
res.send("item saved to database")
// `req.user` contains the authenticated user.
//res.redirect('/profile/' + req.body.username);
})
.catch(err => {
console.log(err);
res.status(400).send("unable to save to database");
})
}
})
})
The example above is based on express framework, but you can fit it with no problems to your own case.
Next step is include passport local strategy. // load all the things we need var LocalStrategy = require('passport-local').Strategy;
// load up the user model var User = require('../models/user');
// expose this function to our app using module.exports module.exports = function(passport) {
// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and unserialize users out of session
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
// =========================================================================
// LOCAL LOGIN =============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-login', 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) { // callback with email and password from our form
// 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 before anything else
if (err)
return done(err);
// if no user is found, return the message
if (!user)
return done(null, false, {message: 'User not found.'}); // req.flash is the way to set flashdata using connect-flash
// if the user is found but the password is wrong
if (!user.validPassword(password))
return done(null, false, {message: 'Incorrect password.'}); // create the loginMessage and save it to session as flashdata
// all is well, return successful user
return done(null, user);
});
}));
};
We have only signin task now. It's simple.
app.post('/login', function(req, res, next) {
passport.authenticate('local-login', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.send(info.message); }
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.send(user.local.username);
});
})(req, res, next);
});
Upvotes: 2
Reputation: 12542
Passport localStrategy
doesn't have res
in the callback. It's req, username, password and done. Here is an example.
passport.use('local-signup', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
// request object is now first argument
// ...
}
));
Upvotes: 1