使用res.locals.user在所有前端视图中显示用户对象

时间:2017-11-13 13:43:22

标签: javascript node.js

我正在尝试使用res.locals.user来显示前端中的user对象。

下面你可以在我的主app.js文件中看到我创建的中间件:

...    
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()
})
...

我的护照文件如下所示:

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('/')
}

但是,当我尝试在我的哈巴狗视图中显示user对象时,我收到以下错误:

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

在我正确登录用户后,为什么用户对象在视图中不可用的任何建议?

2 个答案:

答案 0 :(得分:1)

修改[1] 您的应用中需要2个输入视图:

  1. 对于用户通过身份验证的情况,index
  2. 案例用户的loginPage未经过身份验证
  3. 您也可以在主视图(index)中处理这两种情况,但您需要根据currentUser的存在来显示/隐藏元素。但我发现单独的观点更加清晰。

    第1步 - 添加您的身份验证中间件:

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

    第2步 - 渲染您的应用根/在您注册auth中间件后执行此操作非常重要,以便填充res.locals.user ):

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

    第3步 - 将注入的用户添加到window中的index.pug

    if !!currentUser
        script.
            window.currentUser = !{currentUser}
    

答案 1 :(得分:0)

isAuthenticated函数中,req.session.userundefined 对于每个经过身份验证的路由,Passport.jsuser对象存储在req.use中,会话仅存储userId。

middleware app.jsisAuthenticated文件正常,但res.locals.user覆盖undefinedmiddleware

在我看来,您需要删除isAuthenticated(因为它在所有路线中使用)并更改exports.isAuthenticated = (req, res, next) => { if (req.isAuthenticated()) { res.locals.user = req.user return next() } res.redirect('/') } ,如下所示:

result = func();
if(result == -1)
        return func2();
else
    return result;