Page Contents

See also: Example in LoopBack repository.

LoopBack applications sometimes need to access context information to implement the business logic, for example to:

  • Access the currently logged-in user.
  • Access the HTTP request (such as URL and headers).

A typical request to invoke a LoopBack model method travels through multiple layers with chains of asynchronous callbacks. It’s not always possible to pass all the information through method parameters. 

Fixing deprecation warnings

All context-related LoopBack APIs are deprecated starting with version 2.30.0. After upgrading an existing application to a recent LoopBack version, you will see the following deprecation warning:

loopback deprecated loopback#context middleware is deprecated.
See https://docs.strongloop.com/display/APIC/Using%20current%20context for more details.
node_modules/loopback/server/middleware/rest.js:60:32

To remove this warning, disable the context middleware added by the built-in REST handler. Set the remoting.context property in server/config.json to false; for example:

server/config.json

{
  "remoting": {
    "context": false,
    // etc.
  },
  // etc.
}

If your application relies on loopback.getCurrentContext, then you should rework your code to use loopback-context directly, per the following instructions.

Install loopback-context

Add loopback-context to your project dependencies

$ npm install --save loopback-context

Configure context propagation

To setup your LoopBack application to create a new context for each incoming HTTP request, configure per-context middleware in your server/middleware.json as follows:

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

Use the current context

Once you’ve enabled context propagation, you can access the current context object using LoopBackContext.getCurrentContext(). The context will be available in middleware (if it is loaded after the context middleware), remoting hooks, model hooks, and custom methods.

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

MyModel.myMethod = function(cb) {
  var ctx = LoopBackContext.getCurrentContext();
  // Get the current access token
  var accessToken = ctx && ctx.get('accessToken');
  ...
  // Set more information on current context
  ctx.set('foo', { bar: 'val' } );

  ...
}

Use current authenticated user in remote methods

In advanced use cases, for example when you want to add custom middleware, you have to add the context middleware at the right position in the middleware chain (before the middleware that depends on LoopBackContext.getCurrentContext).

Here’s sample code which uses a middleware function to place the currently authenticated user into the context so that remote methods may use it:

/server/server.js

...
// -- Add your pre-processing middleware here --
app.use(LoopBackContext.perRequest());
app.use(loopback.token());
app.use(function setCurrentUser(req, res, next) {
  if (!req.accessToken) {
    return next();
  }
  app.models.UserModel.findById(req.accessToken.userId, function(err, user) {
    if (err) {
      return next(err);
    }
    if (!user) {
      return next(new Error('No user with this access token was found.'));
    }
    var loopbackContext = LoopBackContext.getCurrentContext();
    if (loopbackContext) {
      loopbackContext.set('currentUser', user);
    }
    next();
  });
});

// boot scripts mount components like REST API
...

/common/models/YourModel.js

var loopback = require('loopback');
var LoopBackContext = require('loopback-context');
module.exports = function(YourModel) {
  ...
  //remote method
  YourModel.someRemoteMethod = function(arg1, arg2, cb) {
    var ctx = LoopBackContext.getCurrentContext();
    var currentUser = ctx && ctx.get('currentUser');
    console.log('currentUser.username: ', currentUser.username); // voila!
    ...
    cb(null);
  };
  ...
};