You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LoopBack中before save钩子无法通过ctx访问外部模型与请求对象

Solution for Accessing Request Data & External Models in LoopBack's Operation Hooks for the Org Model

I've run into similar issues with LoopBack 3's operation hooks before, so here are practical fixes for your problems:

1. Get Request Object, URL, HTTP Method, and User ID

The default operation hook context (ctx) doesn't include the request object directly, but you can pass it through using a beforeRemote hook or use the loopback-context module.

Option 1: Pass Request via beforeRemote Hook (Most Reliable)

This method attaches the request to the hook's options, making it accessible in any subsequent operation hooks:

module.exports = function (Org) {
  // Attach req to all remote method options
  Org.beforeRemote('**', function(ctx, _, next) {
    ctx.options.req = ctx.req;
    next();
  });

  // Access request data in your operation hook (e.g., access hook)
  Org.observe('access', function(ctx, next) {
    const req = ctx.options.req;
    if (req) {
      const url = req.originalUrl;
      const httpMethod = req.method;
      // Get userId if your API uses LoopBack's default authentication
      const userId = req.accessToken?.userId;

      console.log('Request URL:', url);
      console.log('HTTP Method:', httpMethod);
      console.log('Authenticated User ID:', userId);
    }
    next();
  });
};

Option 2: Use loopback-context for Global Access

If you prefer a global approach, install the loopback-context module first:

npm install loopback-context

Then add the middleware to server/middleware.json:

"initial": {
  "loopback-context#per-request": {}
}

Now you can fetch the request in your operation hook:

const LoopBackContext = require('loopback-context');

module.exports = function (Org) {
  Org.observe('access', function(ctx, next) {
    const currentCtx = LoopBackContext.getCurrentContext();
    if (currentCtx) {
      const req = currentCtx.get('req');
      const url = req.originalUrl;
      const httpMethod = req.method;
      const userId = req.accessToken?.userId;

      // Use the data as needed
    }
    next();
  });
};

Note: This can have context loss issues with async operations, so the beforeRemote method is generally safer.

2. Access External Models

You don't need ctx to access other models—use the Org model's app property to fetch any registered model:

module.exports = function (Org) {
  Org.observe('access', async function(ctx, next) {
    // Fetch an external model (e.g., User)
    const User = Org.app.models.User;
    
    // Example: Fetch a user using the userId from the request
    const req = ctx.options.req;
    if (req?.accessToken?.userId) {
      const user = await User.findById(req.accessToken.userId);
      console.log('Fetched User:', user);
    }
    next();
  });
};

Just make sure the external model is registered in server/model-config.json—this works for any model you've set up in your LoopBack app.

Quick Notes

  • This assumes you're using LoopBack 3 (your code syntax matches it). For LoopBack 4, the approach is different.
  • To get userId, ensure your API has authentication enabled (using LoopBack's built-in AccessToken model or a third-party auth component).
  • Different operation hooks (e.g., before save, after delete) will have slightly different ctx structures, but options is consistently available to pass custom data.

内容的提问来源于stack exchange,提问作者Gary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:16:14