LoopBack自定义路由获取当前登录用户ID及ctx.options为空问题
解决LoopBack自定义路由中before save钩子无法获取用户信息的问题
看起来你遇到的问题是在自定义路由里调用模型的create方法时,before save钩子中的ctx.options为空对象,拿不到当前登录用户对吧?这是因为自定义路由里不会自动把请求上下文传递给模型方法,得手动处理才行,我来给你一步步说怎么解决:
问题原因
LoopBack的内置REST API会自动将请求中的用户信息(比如经过认证后的req.user)注入到模型方法的options参数里,但自定义路由是你自己写的Express风格路由,框架不会帮你做这件事,所以直接调用logs.create()时,options就是空对象,钩子自然拿不到用户。
修复步骤
1. 修正自定义路由中的create调用
首先你代码里的logs.create(logs,(err,obj)=>{...})参数有问题,第一个参数应该是你要创建的日志数据对象,不是模型本身。另外要把当前请求的用户信息通过options传递进去:
// routes.js 里的自定义路由 app.get('/logs/dl',(req,res)=>{ // 假设你已经通过LoopBack的认证机制拿到了req.user(比如JWT认证) const logData = { /* 这里是你要创建的日志数据,比如content: '下载操作日志' */ }; // 把用户信息放到options里传递给create方法 logs.create(logData, { user: req.user }, (err, obj)=>{ if(!err) { res.status(200).send(obj); } else { res.status(500).send(err.message); } }); });
2. 在before save钩子中获取用户
现在你再看钩子的ctx.options,就能拿到你传递的user对象了:
'use strict'; module.exports = function (logs) { logs.observe('before save', async (ctx, next) => { console.log(ctx.options.user); // 现在就能输出当前登录用户了 // 你还可以在这里把用户信息关联到日志上,比如: if (ctx.instance) { ctx.instance.createdBy = ctx.options.user.id; ctx.instance.createdByName = ctx.options.user.username; } await next(); }); };
额外注意点
- 确保你的自定义路由已经经过认证中间件处理,这样
req.user才会存在。如果还没加认证,可以在路由里加上LoopBack的authenticate中间件:const { authenticate } = app.models.User; app.get('/logs/dl', authenticate('jwt'), (req,res)=>{ // 上面的路由处理代码 }); - 如果你用的是LoopBack 4,写法会略有差异,但核心思路一致:把请求上下文里的用户信息传递给模型方法的options参数。
内容的提问来源于stack exchange,提问作者beNerd
相关产品推荐
相关产品推荐

