如何将AdminJS与pino-http集成并记录带管理员ID的请求?
解决AdminJS请求日志与管理员身份记录问题
一、接入AdminJS并通过pino-http记录HTTP请求
确保pino-http中间件在AdminJS路由之前挂载,这样所有AdminJS相关请求都会被日志捕获:
const express = require('express'); const pinoHttp = require('pino-http'); const app = express(); // 初始化pino-http日志中间件,放在所有路由之前 app.use(pinoHttp({ // 先预设自定义字段,后续完善身份信息 customProps: (req, res) => ({ accountId: null, isAdmin: false, }), // 可根据需求配置日志格式、输出目标等 })); // 挂载AdminJS路由 app.use('/admin', adminbroRouter);
二、获取管理员ID并区分用户身份
你遇到的req.user为空的问题,是因为AdminBroExpress.buildAuthenticatedRouter的认证逻辑独立于passport,不会自动将用户信息挂载到req.user。可以通过以下两种方案解决:
方案1:直接从express-session读取AdminJS用户信息
AdminJS会将认证成功的用户对象存储在req.session.adminUser中(默认存储键),直接在customProps中提取即可:
app.use(pinoHttp({ customProps: (req, res) => { const adminUser = req.session?.adminUser; return { accountId: adminUser?.id || null, isAdmin: !!adminUser, // 认证通过的用户都是管理员 }; }, }));
方案2:手动将AdminJS用户挂载到req.user
如果希望统一用req.user获取用户信息,可以在AdminJS路由前添加一个中间件,将session中的AdminJS用户同步到req.user:
// 在挂载AdminJS路由前添加中间件 app.use('/admin', (req, res, next) => { // 将AdminJS存储的用户同步到req.user if (req.session?.adminUser) { req.user = req.session.adminUser; } next(); }, adminbroRouter); // 此时pino-http的customProps即可正常读取req.user app.use(pinoHttp({ customProps: (req, res) => ({ accountId: req.user?.id || null, isAdmin: !!req.user, }), }));
补充说明
- 由于你的认证逻辑中已经通过
AuthService.isAdmin验证了管理员身份,所以session中存在的adminUser必然是管理员,无需再次校验。 - 如果需要确认session存储键是否为
adminUser,可以在认证成功后打印req.session查看结构,调整对应键名即可。
内容的提问来源于stack exchange,提问作者PirateApp
相关产品推荐
相关产品推荐

