2

req.user not accessible anywhere except its origin function.

I read that passport attaches the user to every request after authentication.

I want to stop any user from accessing the inner pages through the url bar thus skipping the login page or if his session is already active he must be redirected to the user page. These two things can be done only if I get access to req.user in all the middlewares.

app.js link

app.js:-

app.post('/',passport.authenticate('local',{failureRedirect: '/'}),
function(req,res,next){
console.log(req.user); //req.user defined here only not in users.js
res.redirect('/users');
});

users.js:-

router.get('/users', function(req, res, next) {
console.log(req.user);//undefined    
res.render('users');
});

DeserializeUser:-

passport.deserializeUser(function(id, done) {
db.findById(id, function(err, user) {
done(err, user);
console.log(user) //undefined 
});
});
line-segment
  • 369
  • 5
  • 14

2 Answers2

5

It doesn't look like your app is set up to support sessions, which is generally what's needed for Passport to "remember" that a user has logged in, and to populate req.user.

The most common session middleware for Express is express-session, and it relatively easy to set up.

For a quick check, to see if this is the problem, you can add the following to your app:

app.use(session({ secret: 'super secret' }));

Make sure you add it before app.use(passport.session()).

If that works, you should read up on how to configure a session store, and what the various other options of the session middleware are.

robertklep
  • 198,204
  • 35
  • 394
  • 381
  • What exactly isn't working, `req.user` isn't defined? Can you add the middleware that you're using to determine if a user has logged in or not to your question? – robertklep Jun 30 '16 at 18:46
  • Yes req.user isn't defined in routes. Added snippets in the question. – line-segment Jun 30 '16 at 18:53
  • It would still depend on how exactly `users.js` fits into your app. The version of the app on GH doesn't show that. Can you check your browser's devtools to see if a session cookie gets set? Also, it would help to add a `console.log()` to `passport.serializeUser/deserializeUser` to see if they get called. – robertklep Jun 30 '16 at 18:59
  • I figured that my deserializeUser is also giving user undefined. Adding the code. – line-segment Jun 30 '16 at 19:02
  • users.js is in the routes folder. Add a cookie named connect.sid – line-segment Jun 30 '16 at 19:10
  • So the issue now becomes: why is `user` in `deserializeUser` undefined? It looks like `user` [here](https://github.com/ehra/hostelPEB/blob/master/app.js#L47) is undefined (should be `student`?), that might have something to do with it. Also, I assume that the documents from your database have an `id` property, because that is what `serializeUser` uses [here](https://github.com/ehra/hostelPEB/blob/master/app.js#L17). – robertklep Jun 30 '16 at 19:17
  • Thanks Sir! Actually database wasn't being accessed in deserialize wrong object name. Didn't know deserialize was double checking the user info in the database. Do you know why it is querying the database again if the user object is already there? I read [here](http://stackoverflow.com/questions/27637609/understanding-passport-serialize-deserialize) but whats the need of querying the database again if you already have the object 'user'. – line-segment Jun 30 '16 at 19:38
  • That has to do with sessions: in `serializeUser`, you determine what should be stored in the session data (in this case, `user.id`). This is to keep the sessions small. To "translate" that session data into a full user document again, `deserializeUser` gets the session data (the id) and asks the database for the full user document. You can also store the entire `user` object in the session if you want, but that would make your session storage grow (and ultimately, this is usually _also_ stored in a database and also has to be queried). – robertklep Jun 30 '16 at 19:42
  • Also see [this answer](http://stackoverflow.com/questions/37559391/questions-about-how-passport-js-works-specifically-about-user-id/37562849#37562849) I wrote a while back. – robertklep Jun 30 '16 at 19:44
  • So can I say whenever I'm accessing req.user deserializeUser is invoked? – line-segment Jun 30 '16 at 19:47
  • `deserializeUser` is invoked for every request that a) is passed through the `passport.session()` middleware and b) is accompanied by a session cookie, which generally is for all routes in which you need to access `req.user`. – robertklep Jun 30 '16 at 19:49
0

create a middleware function with this : passport.authenticate('local',{failureRedirect: '/'}) as content and use it in every route you wanna authenticate. Or use it in app.use(that_function) to authenticate whole app

Akarsh Satija
  • 1,756
  • 2
  • 22
  • 28
  • But that would trigger the username password authentication every-time.If I have already authenticated the user then I must only verify this in routes using req.user. – line-segment Jun 30 '16 at 18:13
  • Not if you setup session for your login. use this boilerplate to understand [`https://github.com/meanjs/mean/tree/v0.3.3`](https://github.com/meanjs/mean/tree/v0.3.3) PS:check for the 0.3 version only. passport.js in config and strategies, will help you understand – Akarsh Satija Jun 30 '16 at 18:20
  • Added that middleware but its giving me req.user=null. Atleast some progress. – line-segment Jun 30 '16 at 18:37
  • That's cause in the routes I haven't added the passport.use its in app.js and its calling passport.use which doesn't exist there. – line-segment Jun 30 '16 at 18:40