Minimalist authorisation mechanism for node servers
Minimalist authorisation mechanism for node servers . Designed for efficient use in GraphQL servers, authorizr allows
flexible and easy to reason about authoristion checks. By creating a new authorizr object per request, the implementation
is free to pre-optimise as much or as little of the heavy lifting as desired.
I’ve written a little on the idea behind this library on my blog.
npm install authorizr
Create a new authorizr.
import Authorizr from 'authorizr';
// Create a new authorisation object
const authorizr = new Authorizr(context => {
// Do any pre-calculation per instance (eg. get commonly used info from db)
return new Promise((resolve, reject) => {
const teams = db.findUserTeams(context.userId);
const perms = db.findUserPermissions(context.userId);
Promise.all([teams, perms])
.then(res => {
// Resolve the promise with data that is passed into every auth check
resolve({ userId: context.userId, teams: res[0], perms: res[1] })
});
});
});
authorizr.addEntity(
'team',
{
// Each check function is passed the pre-calculated global context, any arguments
// passed into the entity and any arguments passed into the specific check
isOwner: (ctx, entityId, args) => ctx.teams[entityId].owner === ctx.userId,
isAdmin: (ctx, entityId, args) => ctx.teams[entityId].admin === ctx.userId
}
);
Create a new authorizr instance using the context of the request (before the graphql query is executed). This allows the authorizr to
setup all the checks for the user making the request.
req.ctx.auth = authorizr.newRequest(ctx);
Use the checks in an easily readable way in the resolve functions.
resolve: function(id, args, { auth }) {
auth.team(id)
.isOwner()
.isAdmin()
.any()
.then(res =>
if (res) {
// Do protected access
}
}
}
new Authorizr(setupFn [, options])
Create a new Authorizr
instance.
setupFn: A function that accepts arbitrary inputs and does pre-optimisation for each request. Returns an arbitrary object, or a promise resolving to an arbitrary object, that will be passed to each individual authorisation check.
options: An optional object of options:
true
. Set to false to disable caching each authorisation check.addEntity(name, checks)
Adds an entity for doing authorisation checks against.
check(globalCtx, entityArgs, checkArgs)
setupFn
for this request.newRequest(context)
Creates a new context for authorisation calls. The setupFn
will be called as part of this initialisation.
setupFn
. Usually identification about who is making the request.entity(entityId)
Identifies an entity for completing authorisation checks against and returns an object with chainable check methods from the addEntity
call.
check(checkArgs)
Completes an authorisation check using context from the request and entity calls. Th
all()
Returns a promise resolving to true if all the checks passed, otherwise resolving to false.
any()
Returns a promise resolving to true if any the checks passed, otherwise resolving to false.