Express - 自定义身份验证中间件破坏了`req.session`

Express - custom authentication middleware destroys `req.session`

我正在尝试为 Express 创建一个简单的身份验证中间件。 看起来 req.session.user 在使用 requiresAuthentication 时设置为 undefined

我的代码:

user.ts

import { Request, Response } from 'express'

export enum UserRole {
    None = -1,
    Normal = 0,
    Judge = 1,
    Admin = 2
}

export class User {
    public login: string
    public logged: boolean = false
    public name: string
    public passwordHash: string
    public role: UserRole = UserRole.None
}

function addUser(req: Request) {
    if (typeof req.session.user === 'undefined') {
        req.session.user = new User()
    }
}

export function middleware(req: Request, res: Response, next) {
    addUser(req)
    next()
}

export function requiresAuthentication(roles: Array<UserRole>) {
    return (req: Request, res: Response, next) => {
        if (req.session.user.logged === true) {
            if (roles.indexOf(req.session.user.role) !== -1) {
                next();
                return;
            }
        }

        res.status(401).render('authentication_required')
    }
}

app.ts

import * as express from 'express'
import * as bodyParser from 'body-parser'
import * as cluster from 'cluster'
import { cpus } from 'os'
import * as path from 'path'
import * as i18n from 'i18n'
import * as session from 'express-session'
import * as user from './user'
import * as helmet from 'helmet'

const config = {
    debug: true,
    port: 8080,
    session: {
        secret: process.env.SESSION_SECRET || "SECRET_BELCANTO"
    }
}

if (cluster.isMaster && !config.debug) {
    for (let i = 0; i < cpus.length; i++) {
        cluster.fork()
    }

    cluster.on('exit', (worker) => {
        cluster.fork()
    })
} else {
    if (config.debug) {
        console.log('Debug mode')
    }

    let app = express()

    app.use(helmet())
    app.use(bodyParser.urlencoded({ extended: true }))
    app.use(bodyParser.json())

    app.use(session({
        secret: config.session.secret
    }))

    i18n.configure({
        directory: path.join(__dirname, 'locales'),
        locales: [
            'en',
            'pl'
        ]
    })

    app.use(i18n.init)

    app.use('/public', express.static(path.join(__dirname, 'public')))
    app.set('view engine', 'pug')
    app.set('views', path.join(__dirname, 'views'))
    app.use(user.middleware)

    app.get('/', user.requiresAuthentication([user.UserRole.None]), (req, res) => {
        res.render('index', { user: req.session.user })
    })


    console.log(`App listening on ${config.port}`)
    app.listen(config.port)
    console.log('App shutdown')
}

What happens when trying to open localhost:8080

TypeError: /home/kamil/Pulpit/belcanto/app/views/layout.pug:13
    11|         script(src='/public/js/semantic.min.js')
    12| 
  > 13|         unless user.logged
    14|             #loginModal.ui.tiny.modal
    15|                 .header= __("Login")
    16|                 .content

Cannot read property 'logged' of undefined
    at eval (eval at wrap (/home/kamil/Pulpit/belcanto/node_modules/pug-runtime/wrap.js:6:10), <anonymous>:24:11)
    at template (eval at wrap (/home/kamil/Pulpit/belcanto/node_modules/pug-runtime/wrap.js:6:10), <anonymous>:173:4)
    at Object.exports.renderFile (/home/kamil/Pulpit/belcanto/node_modules/pug/lib/index.js:428:38)
    at Object.exports.renderFile (/home/kamil/Pulpit/belcanto/node_modules/pug/lib/index.js:418:21)
    at View.exports.__express [as engine] (/home/kamil/Pulpit/belcanto/node_modules/pug/lib/index.js:465:11)
    at View.render (/home/kamil/Pulpit/belcanto/node_modules/express/lib/view.js:127:8)
    at tryRender (/home/kamil/Pulpit/belcanto/node_modules/express/lib/application.js:640:10)
    at Function.render (/home/kamil/Pulpit/belcanto/node_modules/express/lib/application.js:592:3)
    at ServerResponse.render (/home/kamil/Pulpit/belcanto/node_modules/express/lib/response.js:971:7)
    at /home/kamil/Pulpit/belcanto/app/user.js:35:25

--编辑--

addUser 中添加 req.session.save((err) => {}) 无法解决问题。

我的猜测是 authentication_required.pug 取决于 layout.pug,但您没有在此处传递 user

res.status(401).render('authentication_required')

堆栈跟踪显示它开始出错的地方:

Cannot read property 'logged' of undefined
    ...
    at /home/kamil/Pulpit/belcanto/app/user.js:35:25