As per this article
http://toon.io/understanding-passportjs-authentication-flow/
it looks as though PassportJS/Express store the logged in user in two places
req.user
and
req.session.passport.user
why both? which one should I use? When I logout with passport, does it destroy both req.user and req.session.passport.user?
You should always, always use req.user in your own code -- this is important because if you use req.session.passport.user, you're essentially pulling user information out of a session cookie (which may be outdated).
It's always best to rely on req.user as opposed to cookie data directly, as depending on your implementation, that information might be out of date.
And to answer your question: if you log a user out, both req.session and req.user will no longer be available.
Related
I have a question about the usage of sessions with express-session. I really don't understand how the sessions are secure. For example in the following official guide: https://expressjs.com/en/resources/middleware/session.html they create a middleware to check if the user is authenticated:
// middleware to test if authenticated
function isAuthenticated (req, res, next) {
if (req.session.user) next()
else next('route')
}
But I don't understand, why isn't this middleware checking that the session is in fact, inside the DB? An attacker could just modify the session cookie with random values and there would be still some value in the user field, even if it's a garbage value, no? So the function still would think this is an authenticated user.
Why is this not possible?
In my case, I am setting the userId in the session and then every time someone makes a request, I retrieve its userId, but I do not understand, what if someone modifies the cookie and gets a random userId value? My application will think this user is authenticated, correct?
why isn't this middleware checking that the session is in fact, inside the DB?
This check, which you rightly expect to be done, is already done before, in the express-session middleware: This looks up the value of the session cookie in the session storage (which can be a database) and populates req.session accordingly. Since the value of the session cookie is unguessable, an attacker who puts in a random value, will make req.session undefined, and the isAuthentication check will fail, as it should.
According to this question, user data should live on res.locals.user but in Passport.js examples, this data is put on req.user.
Why did Passport.js not follow the res.locals convention?
req.local is just a place where user email and password is store.You can store it any other variable name also.
Basically passport manage things, you can customize all these things as per your requirement.
People follow this structure due to :
local :{name ,password}
google :{token,refresh},
fb..... and so on so its easy to search during login
Alrigh, so I have set up an entire passport local authorization, every thing works pretty perfectly, except I can't seem to wrap my head around one issue with passport.js.
I am authorizing users through sessions (they work fine), however I can't seem to extract the user info from that session, although if I manually check my session db, for every session there is a userid (which links to the user).
Also the deserialize functions seem to return the user and the log is showing the correct user.
Now the problem is that I can't seem to pass this user<->session info anywhere in my routes.
The issue that I seem to have with this is that people that are logged in, are authorized, but they can fiddle with the request body as much as they like, doing things as posting messages in their name, logging them out, ...
Code example:
router.post('/games/:id/verify', isAuthenticated, function(req, res){
log('#POST verify for game with id: ' + req.params.id);
gameController.postVerify(req.params.id, req, res);
});
In this code, it just checks if a user is logged in, if possible, I want to check which user is logged in to that session, so that he cannot verify this game if he was not part of it.
Let's say user A, B were part of the game and need to verify it. This function allows user C who is logged in to verify for them, because this function only checks if the user is logged in.
If I can pass the logged in user (user C in the test case) to the gameController, I can write my own checks in there and throw them out.
Passport will populate req.user when authentication has succeeded. It will be populated by the data provided by deserializeUser, which generally is a database record of the user.
You can use that information to limit other database queries/checks/etc to make sure that the logged-in user is allowed to access particular information.
I am using node/express with passport in my development. I came across an article which says:
Express loads the session data and attaches it to the req. As passport stores the serialised user in the session, the serialised user object can be found at req.session.passport.user.
But to my surprise, the value for sessionID stores in the browser cookies remain the same before and after login. So where does the serialised user object is stored?
I thought that it was stored in the user sessionid cookie initially but it seems that this is not the case as I still can access my user object with req.session.passport.user
So where does the serialised user object is stored?
In Short
The serialized user object is stored in req.user by PassportJS taken from req.session.passport.user (which is is populated by Express) with the help of Passport's deserializeUser method.
Express adds the id of the session object into a cookie on user's browser, which is sent back to express in a header on every request. Express then takes the id from the header and search the session store (i.e. Mongo or whatever) and find the entry and load it to req.session.
PassportJS uses the content of req.session to keep track of the authenticated user with the help of serializeUser and deserializeUser methods (for more information on workflow of serializeUser and deserializeUser see my answer in this SO question).
Express is responsible for creating the session. when does the sessions gets created? That is when Express do not detect a session cookie. So the order in which you organize your session and passport configs in your app or server.js file is very important. If you declare your session and passport configs above static directory configs then all requests for static content will also get a session, which is not good.
See my answer to this SO question, where I have mentioned about static content access as well as how to selectively apply passport to certain routes, rather than default (you might not need to authenticate all the routes - hence you could avoid unnecessary session store lookup and de-serialization by attaching session only to requests that map to secure URLS see below).
//selectively applying passport to only secure urls
app.use(function(req, res, next){
if(req.url.match('/xxxx/secure'))
passport.session()(req, res, next)
else
next(); // do not invoke passport
});
There is one amazing tutorial that I highly recommend you to read up if you want to understand the workflow of PassportJS.
You can look at the sessionID in the cookie as a key to a database where the session data is stored. Depending on what session handler you use with express, and what storage policy you use the data will be stored in different ways. This means that the sessionID can be the same value both before login, after a successful login, and even after a user logs out.
If you use express-session with MemoryStore the data will be saved in the memory of the node process, indexed on the sessionID. Look here for initialization of the store and here for storing of the data.
You could create a store where the data is serialized to the cookie, but none such are listed in the compatible session stores.
I finally got done replacing an everyauth/ mongoose-auth login system with a passport implementation. I'm using this purely for local username/ password logins, so I'm also utilizing the passport-local module as well.
I know from looking through a few examples, I found Passport auto-assigns a couple req helpers. I've not been able to find a full list of variables it puts there though, a couple I've found are req.isAuthenticated() and the req.user variables.
Is there a full list provided anywhere online? Just interested in my options available in routes/ views. I can keep trolling through examples, but it would be nice if there was a reference somwhere.
For a Connect/Express application,
1.var passport = require('passport');
The following four helper functions are added to http.IncomingMessage.prototype(i.e., the request object's prototype):
login/logIn(user, [options,] done)
logout/logOut()
isAuthenticated() - i.e. whether req.user exists.
isUnauthenticated()
If a user is authenticated successfully, usually a callback function done(null, user) is called. This callback function then calls req.logIn() which in turn calls serializeUser() to store the user id as req._passport.session.user.
The req.logOut() function deletes req._passport.session.user.
2.app.use(passport.initialize());
Get the passport info from current session and store it as req._passport.session(i.e., req.session['passport']).
3.app.use(passport.session());
Check whether req._passport.session.user exists, that is, whether the user id is stored in current session. If yes, call deserializeUser() to get the user object which will be stored as req.user.