I have to know when Serialize and Deserialize called, for testing I have put alert(user.id)
but no action happened.
I have some queries:
user
object has received in passport.serializeUser(function(user, done){...
process.nextTick()
herefunction(req, email, password, done)
, if I send multiple form values e.g(name, email, password, address, mobile).Here is the code:-
//config/passport.js
var LocalStrategy = require('passport-local').Strategy;
var User = require('../app/models/user');
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
alert(user.id);//// Here is my testing alert
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use('local-signup', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
process.nextTick(function() {
User.findOne({ 'local.email' : email }, function(err, user) {
if (err)
return done(err);
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
var newUser = new User();
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
}
Passport uses serializeUser function to persist user data (after successful authentication) into session. Function deserializeUser is used to retrieve user data from session.
Serialization is a mechanism of converting the state of an object into a byte stream. Deserialization is the reverse process where the byte stream is used to recreate the actual Java object in memory. This mechanism is used to persist the object.
Passport's middleware is built in a way that allows you to use multiple strategies in one passport.
Serialization is the process of converting a data object—a combination of code and data represented within a region of data storage—into a series of bytes that saves the state of the object in an easily transmittable form.
Based on my knowledge of using Passport.js for a project, I will try to answer as much as I can.
First of all, there is nothing (function) like alert()
in nodejs, so you would have to rename your alert(...)
which is a browser thing, to something like console.log(...)
I cannot see your app.js file so, I will go ahead and try to answer your queries based on my experience of using passportjs.
Assuming that you have following in your app.js
(order is important, see here)
var passport = require('passport');
// express-session configs here
// following is invoked on each request.
app.use(passport.initialize());
passport.initialize()
and passport.session()
are invoked on each request and they are the ones that cause serializeUser
to load the user id to req.user
if a serialized user is found in the server (when using mongodb, if the user exist in mongodb).
passport.session()
calls deserializeUser
on each request, which queries the mongodb using the user._id
that was initially loaded to req.user
by serializeUser
and stores the more information about user in the req.user
.
process.nextTick()
defers the execution of the callback until the next pass around the event loop. Database querying is sync in nature and process.nextTick()
make it asynchronous. There is lots of tutorials about this, Google it.
As mentioned earlier, app.use(passport.session())
runs deserializeUser
on each request (basically every request - if you list your express static path configs after passport.session()
then even for requests that load static files). In my case, I needed authentication on specific routes and I wanted to do the authentication, deserializeUser
etc to occur only when the user accesses a secure path hence, I had to put a condition to invoke passport.session()
only when the path matched certain pattern as follow:
app.use(function(req, res, next){
if(req.url.match('/xxxx/secure'))
passport.session()(req, res, next)
else
next(); // do not invoke passport
});
Replacing app.use(passport.session())
with above helped. Now only when the user access secure paths, the passport process is invoked including serializeUser
and deserializeUser
. I am not sure if above is the perfect solution but, it greatly helps in reducing the amount of unnecessary querying of mongodb for user (deserializeUser).
Not sure what you are asking in your last point. There are quite a few tutorials that shows how to implement passportjs for local as well as social auth. You should have a look around.
MORE READING
For more interesting facts on how the session
is loaded with user, read my answer in this SO question. It describes what Express
does? what PassportJS
does? and you will understand the the workflow easily (documentation makes it confusing and ambiguous).
Your 3rd point is
How to call callback function
function(req, email, password, done), if send multiple form values e.g(name,email,password,address,mobile).
As per my understanding,4th argument takes as a call back function.you can not use like and throw error
function(req, email, password, mobile, address, done)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With