License MIT - Copyright Nicolas Chambrier naholyr@gmail.com
- You can use this module with Express or any other Connect-based application
- You'll find an application middleware to configure access control layer
- You'll be able to globally protect a list of paths in your application, or...
- ... protect any action, one by one, using the route middleware
From NPM (easiest and best way):
npm install connect-access-control
From Git (if you want to contribute, or get a dev version):
git clone http://github.com/naholyr/connect-access-control.git node_modules/connect-access-control
Load the middleware:
var accessControl = require('connect-access-control');
Enable access control in your application:
app.use(accessControl(options));
If you use default retrieve
and save
options, you must have enabled session support before enabling access control:
app.use(connect.middleware.session(...));
app.use(accessControl(...));
The middleware will populate request with a new key "user" (see option reqKey
to customize this). req.user
will provide the following methods:
grant(roles, callback)
add role(s) to user, and call callback() after credentials are savedrevoke(roles, callback)
remove role(s) from user, and call callback() after credentials are savedrevokeAll(callback)
remove all roles from user, and call callback() after credentials are savedisSuperAdmin()
checks if user has a super-admin rolegetRoles()
returns the list of user's roleshas(roles)
checks if user matches the given combination of roles (see "Checking roles")login(callback)
marks user as logged in, retrieve his initial roles (see optioninitialize
), and call callback() after credentials are savedlogout(callback)
marks user as logged out, and call callback() after credentials are savedisLoggedIn()
checks if user has been marked as logged in
Global options:
accessControl.securedPaths
list of automatically secured paths (called "global protection"), each one can be a string (exact path) or a regular expressionaccessControl.requiredLoggedIn
set to true if global protection should require to be logged inaccessControl.requiredRoles
roles that must be required for globally protected pagesaccessControl.ignoredPaths
list of paths that won't trigger the access control (noreq.user
created), each one can be a string (exact path) or a regular expressionaccessControl.superAdmin
list the roles that will be considered as super-admin rolesaccessControl.limitedAccessCallback
will be called for secured pages with required roles that are not matched (function(req,res,next)
)accessControl.notLoggedInCallback
will be called for secured pages requiring logged in user (function(req,res,next)
)accessControl.loginPath
the defaultnotLoggedInCallback
will redirect to this pathaccessControl.initialize
will retrieve initial roles from user as soon as he logs in (function(req,callback)
, wherecallback
isfunction(roles or null if nothing loaded)
), default does not initialize anythingaccessControl.retrieve
will retrieve current roles for user (function(req,callback)
wherecallback
isfunction(loggedin,roles)
), default will retrieve from sessionaccessControl.save
will save current roles from user (function(req,loggedin,roles,callback)
) wherecallback
isfunction()
), default will save to sessionaccessControl.reqKey
will allow you to customize how req will be populated, default is "user" to create areq.user
object
Instance options:
ignoredPaths
will be merged with global optionignoredPaths
securedPaths
will be merged with global optionsecuredPaths
requiredLoggedIn
will replace global optionrequiredLoggedIn
requiredRoles
will replace global optionrequiredRoles
superAdmin
will be merged with global optionsuperAdmin
initialize
will replace global optioninitialize
retrieve
will replace global optionretrieve
save
will replace global optionsave
Globally (this is not the best way in my opinion, but maybe the easiest at beginning):
// Global protection
accessControl.securedPaths.push('/private');
// Globally protected pages require login
accessControl.requiredLoggedIn = true;
// Globally protected pages require role "authorized"
accessControl.requiredRoles.push("authorized");
Per page:
// Require logged in
app.get('/private', accessControl.secure(true), function (req, res) { ... });
// Require role "admin" or "moderator"
app.get('/moderate', accessControl.secure([["admin", "moderator"]]), function (req, res) { ... });
Look at the sample Express application provided in the sample
directory.
The way roles are required is directly inspired by symfony's credentials system. You can imbricate arrays to alternate AND and OR operations.
Here are some examples that will explain this system more easily than the full explanation ;)
["role1", "role2] role1 AND role2
[["role1", "role2"]] role1 OR role2
["role1", ["role2", "role3"]] role1 AND (role2 OR role3)
["role1", ["role2", ["role3", "role4"]]] role1 AND (role2 OR (role3 AND role4))
As you see, the first level of array = AND operation, then each time you add a level you alternate: OR, then AND, then OR, etc...
With this simple system you can declare any complex combinations of roles to secure your pages.
1.0.0
2011-07-30: Initial release