Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using res.locals.user to show user object in all frontend views

I am trying to use res.locals.user to show the user object in the frontend.

Below you can see in my main app.js file the middleware I have created:

...    
const passport = require('passport')

const auth = require('./routes/auth')
const index = require('./routes/index')

const app = express()

// view engine setup
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'pug')
app.use(logger(process.env.LOG_ENV))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
  extended: false,
}))
app.use(express.static(path.join(__dirname, '/../public')))
app.use(cookieParser())

app.use(session({
  secret: 'super-mega-hyper-secret',
  resave: false,
  saveUninitialized: true,
}))
app.use(passport.initialize())
app.use(passport.session())
app.use((req, res, next) => { //This middleware checks the local user
  res.locals.user = req.user
  next()
})
...

My passport file looks like the following:

const passport = require('passport')
const LocalStrategy = require('passport-local').Strategy
const serviceAuth = require('../service/auth')

passport.serializeUser((user, done) => {
  done(null, user.id)
})

passport.deserializeUser(async(id, done) => {
  const user = await serviceAuth.findById(id)
  done(null, user)
})

// Sign in with username and Password
passport.use('local', new LocalStrategy({
  usernameField: 'username',
}, async(username, password, done) => {
  const user = await serviceAuth.signin(username, password)
  done(null, user)
}))


/**
 * Login Required middleware.
 */
exports.isAuthenticated = (req, res, next) => {
  if (req.isAuthenticated()) {
    res.locals.user = req.session.user
    return next()
  }
  res.redirect('/')
}

However, I get the following error, when trying to display in my pug view the user object:

TypeError: /home/ubuntu/workspace/src/views/includes/_sidebar.pug:6
    4|          .user-panel
    5|                  .pull-left.info
  > 6|                          p= user.name
    7|                          p= user.role
    8| 
    9|          // Sidebar Menu

Cannot read property 'name' of undefined

Any suggestions why the user object is not available in the views AFTER I have properly logged in a user?

like image 348
Carol.Kar Avatar asked Sep 15 '25 02:09

Carol.Kar


1 Answers

EDIT[1] You will need 2 entry views in your app:

  1. A index for the case a user is authenticated
  2. A loginPage for the case user is not authenticated

You can also handle these both cases in the main view(index) but you need to show/hide elements based on the presence of the currentUser. But i find having separate views more clean.

Step 1 - add your authentication middleware:

const isAuthenticated = require('./path/to/isAuthenticated');
app.use(isAuthenticated)

Step 2 - render your app root / (is very important to do this after you registered the auth middleware so that your res.locals.user is populated):

app.get('/', function(req, res){
    if(res.locals && res.locals.user){
        res.render('index', { currentUser: res.locals.user });
    } else {
        res.render('loginPage');
    }            
});

Step 3 - Add the injected user to the window in index.pug:

if !!currentUser
    script.
        window.currentUser = !{currentUser}
like image 59
AndreiC Avatar answered Sep 16 '25 15:09

AndreiC