Search code examples
node.jsmongodbexpressmongoose

How to check if user is logged in with node.js and mongoose


So I want let's say p.x on /profile I want to know if the user is logged in with a command!

So when he goes to home page "/" it's going to render either the profile.ejs if he is logged in or the home.ejs to register and log in.But I don't when do that with app.get('/login'... because I need it again when I am already using the profile to redirect to another page but he has to be logged in to go there.

Here is code:

if (process.env.NODE_ENV !== 'production') {
  require('dotenv').config()
}

const express = require('express')
const app = express()
const bcrypt = require('bcrypt')
const passport = require('passport')
const flash = require('express-flash')
const session = require('express-session')
const methodOverride = require('method-override')
const initializePassport = require('./passport-config')
var mongodb = require('mongodb');
const bodyParser = require('body-parser');
initializePassport(
  passport,
  email => users.find(user => user.email === email),
  id => users.find(user => user.id === id)
)

var urlencodedParser = bodyParser.urlencoded({extended:false})
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
const users = []

var http = require('http');

/* ************ */
app.use(express.static(__dirname + '/public'));
app.set('view-engine', 'ejs')
app.use(express.urlencoded({ extended: false }))
app.use(flash())
app.use(session({
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false
}))
app.use(passport.initialize())
app.use(passport.session())
app.use(methodOverride('_method'))


app.use( bodyParser.json() );     

var dbConn = mongodb.MongoClient.connect('mongodb://localhost:27017/');

var path = require('path');

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/nyg', {useNewUrlParser: true});
const Schema = mongoose.Schema;

const userSchema = new Schema({
  email: String,
  password: String
});

const User = mongoose.model('users', userSchema);

app.post('/register', async (req, res, next) => {
  const user = await User.findOne({
    email: req.body.email,
    password: req.body.password
  }).exec();

  if (user) {
    res.redirect('/register');
    next();
  }

  else new User({
    email: req.body.email,
    password: req.body.password
  })
    .save()
    .exec();
  res.redirect('/login');
  next();
});

app.post('/login', async (req, res, next) => {
  const user = await User.findOne({
    email: req.body.email,
    password: req.body.password
  });
  if (user) res.redirect('/');
  else res.redirect('/login');
  next();
});


app.get('/', (req, res) => {
  if (req.isAuthenticated()) res.render('profile.ejs')

  else res.render('index.ejs')
})

app.get('/login', (req, res) => {
  res.render('login.ejs')
})


app.get('/register', (req, res) => {
  res.render('register.ejs')
})


app.delete('/logout', (req, res) => {
  req.logOut()
  res.redirect('/login')
})



app.listen(process.env.PORT || 3000, process.env.IP || '0.0.0.0' );


Solution

  • Passport already contains everything you need to log in a user and check if a user is authenticated in any route.

    You have correctly identified that the req.isAuthenticated() function is provided by the middleware to see if a user is currently authenticated.

    The user must be logged in with Passport for the function to work. In your app.post('/login' route, make sure that you are authenticating the user against Passport like this:

    passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login' }));
    

    The Passport documentation clearly explains how to set it up for username and password authentication if your current configuration isn't working. The examples they give already use mongoose to retrieve users from the database.

    req.isAuthenticated() can then be used in combination with an if statement from any route to conditionally execute code depending on if the user is logged in.

    if (req.isAuthenticated()) {
      // The user is logged in
    } else {
      // The user is logged out
    }
    

    Alternatively, you can create a simple middleware that will only allow access to a route if the user is logged in.

    function loggedIn(req, res, next) {
      if (req.isAuthenticated()) {
        next();
      } else {
        res.redirect('/login');
      }
    }
    

    Use it like this:

    app.get('/protectedRoute', loggedIn, (req, res) => {
      // The user is logged in otherwise they would have been redirected
    })
    

    See my GitHub repo for a fully working express & passport login example. Just follow the instructions in the readme to run it.