jack blank
jack blank

Reputation: 5195

Questions about how passport.js works. Specifically about user.id

I have no id field in my model ,doc, or record or whatever you want to call it. So how come done(null, user.id) works. I have an _id but no id. It looks like a passport object is being added to my session with the _id of the user in the DB, but how did it get the _id is it done automatically? in the docs it says

In this example, only the user ID is serialized to the session

how did it get the id and how did it get the user?

similar example in my code:

passport.serializeUser(function(user, done){
    done(null, user.id)
});

passport.deserializeUser(function(id, done){
    User.findById(id, function(err, user){
        done(err, user);
    })
});

What are the steps that it takes to get the user id?

I also have

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 name"})
            }
      .......

Does the fact that I use passport.use() somehow connect the user in the DB to the passport methods.

Edit lets say I want to transfer the doc (user) via passports on the name field should I use user.name?

Also I'm not really sure about how serializing works

Upvotes: 1

Views: 863

Answers (1)

robertklep
robertklep

Reputation: 203359

So how come done(null, user.id) works. I have an _id but no id.

You're using Mongoose, which adds a so-called virtual getter called id to documents, that returns the _id property. So in your case, both user.id and user._id will work (and will return the same).

Does the fact that I use passport.use() somehow connect the user in the DB to the passport methods.

Yes and no. The strategy that you pass to passport.use() implements the authentication process. You have to implement how the entered user information is validated against your database. In the example code, a call to User.findOne() is made, and the result of that call is checked against the supplied information ("Is username a valid username? If so, is password the password that belongs to this user?").

If the username and password match, the done callback is called with the user document as an argument. This document is what Passport will pass around to various other parts, for instance, to passport.serializeUser() (see below).

Also I'm not really sure about how serializing works.

Serializing is used to store information about the user in a "session object". This object should be able to uniquely identify the user. And since user.id (or user._id) is unique to a user, it's a good property to use.

That's where passport.serializeUser() comes in: it gets passed the user document, and it should provide Passport (by calling the callback function) a uniquely identifying piece of information about that user. Hence done(null, user.id).

The session object itself is also uniquely identified by a "session key". This key is stored in a HTTP cookie and sent to the browser when a user logged in successfully. When the browser opens another page on your website, it sends along that cookie, and using the session key in the cookie, the session object is retrieved from the "session store".

The session object contains the unique user id, but not the rest of the user information. So that's where passport.deserializeUser() comes in: it gets passed the id, and performs a database lookup to retrieve the full user document belonging to that id. This is what Passport will make available as req.user in your route handlers.

If all these steps are executed successfully (which isn't always the case, because cookies can expire, users can get deleted, etc), it will mean that Passport was able to positively identify the user, and they don't have to log in again. At least not until the session expires.

Upvotes: 4

Related Questions