The solution to this problem wasn't terribly obvious, but I came up with something that works well enough, though it's a bit "manual."
First, in my case, I always have access to the user via req.user, which is a fairly common Node.js / Express pattern. I believe libs like Passport follow this as well.
Then, I created a generic helper method called that looks like this:
module.exports.sourceUser = function(ctx) {
var req = ctx.req;
if (!req.user) {
var err = new Error('You must pass valid credentials to call this API.');
err.statusCode = 401;
throw err;
}
return req.user;
};
This will ensure that APIs I attach this method to will require user authentication, rejecting any request that doesn't have a valid user cred.
Next, since I'm defining flat APIs, I'm just defining my own remote methods (not using built-in Loopback ones). Each remote method def looks like this:
Model.remoteMethod('getRecord', {
http: {
verb: 'get',
path: '/:id'
},
accepts: [
{ arg: 'id', type: 'string', required: true, http: { source: 'path' } },
{ arg: 'user', type: 'object', http: helpers.sourceUser }
],
returns: [
{ arg: 'model', type: 'model', root: true }
]
});
You'll need to adjust that code to match your model names, etc. Also, notice the usage of helpers.sourceUser which is the thing that ensures we have a user and then provides that user as an argument to the API implementation.
Finally, I use a where clause in my database queries, etc to ensure that a user only gets/sets their own records (e.g. where model.user == user.id).
Hope this helps someone else...