node_acl用法示例
来源:互联网 发布:java ocr识别 验证码 编辑:程序博客网 时间:2024/06/02 00:27
需要用nodejs实现用户访问控制,有一个node_acl的包可以提供ACL功能,但是没找到什么资料。github上有一个node_acl的demo,翻译一下造福群众。原文地址在这里https://github.com/OptimalBits/node_acl/issues/38
举一个图书的例子,页面路由如下:
/books/books/:bookId/books/:bookId/pages/books/:bookId/pages/:pageId
接下来要考虑每个路径都有哪些行为(action),action有以下四种,都是标准的HTTP查改增删的行为:
get
post
put
delete
这些也是你的权限(permisson)。
角色(role)定义如下:
admin - usually has unlimited access to controlled resourcesuser - has limited access to controlled resourcespublic - has very limited access to controlled resourcesdisabled - has no access to controlled resources
最后是使用者(user),关键是要将user和role对应。当需要检查权限的时候,你只要检查这个user所属的role是否对资源(resource)有权限就行。
(译者注:这里的resource可以理解为对某条路径的访问权限,比如角色admin可以访问/admin路径和/index路径,而角色guest只能访问/index路径)
所以数据结构可以这样设计,一方面要配对roles->resources->permissions,另一方面要配对users->roles
var publicRole = { name: 'public', resources: [ ], permissions: []};var adminRole = { name: 'admin', resources: [ '/books', '/books/:param1', '/books/:param1/pages', '/books/:param1/pages/:pageId' ], permissions: '*'};var userRole = { name: 'user', resources: [ '/books', ], permissions: ['get', 'post']};var allRoles = [ publicRole, adminRole, userRole];
以及
var users = [ { username: 'public', roles: ['public'], password: 'public' }, { username: 'admin', roles: ['admin'], password: 'admin_password' }, { username: 'foobar', roles: ['user'], password: 'barfoo' }];
我要承认我跳过了一些步骤,所以让人困惑。在resources的定义中,我用了”:”符号,这是一个占位符,但实际上node_acl没有这种用法,它仅仅支持字符串的匹配。为了匹配带参数的路径,我们需要generalize paramaterized paths(词穷了,不知道怎么翻),稍后会讲到这一点。
定义了ACL数组和用户数组之后,需要将它们添加到ACL列表中,大概语法像下面那样:
for each role in allRoles for each resource in role.resources node_acl.allow(role.name, resource, role.permissions)for each user in users create a new User(user.username, user.password) as new user on new user created node_acl.addUserRoles(new user.id, user.roles)
(译者注,这里create a new User作者在另一个示例中是用mongodb的entity实现的,另一个示例的链接在本文底部)
这只是一个基础的用法,更高级的用法允许你对资源有更细化的权限。
最后我们来实现access control logic。我们假设用express()框架,用middleware()方法生成的中间件可以很容易将node_acl整合进来
app.get('/books/:bookId', node_acl.middleware(), booksCtrl.getBook)app.put('/books/:bookId', node_acl.middleware(), booksCtrl.editBook)app.delete('/books/:bookId', node_acl.middleware(), booksCtrl.deleteBook)app.get('/books/:bookId/pages', node_acl.middleware(), booksCtrl.listPages)app.post('/books/:bookId/pages', node_acl.middleware(), booksCtrl.addPage)app.get('/books/:bookId/pages/:pageId', node_acl.middleware(), booksCtrl.getPage)app.put('/books/:bookId/pages/:pageId', node_acl.middleware(), booksCtrl.editPage)app.delete('/books/:bookId/pages/:pageId', node_acl.middleware(), booksCtrl.deletePage)
这样就可以自动生成类似如下的代码
func (reqest, response, next) -> node_acl.isAllowed(request.userId, url, httpMethod, func(error, isAllowed) -> if (isAllowed) -> next() else -> response.notAllowed() )
但是我有两点疑问:一个是我原先的应用没有req.userId这个属性,而是req.user.id;还有一个就是我的路径有一些没有显式表明的参数。(笔者注:比如路径中有bookId,你不可能把所有不同bookId的路径都添加到resources里面吧)
所以我不用它自动生成的中间件而是自己写了一个,大约如下:
function myMiddleware(req, res, next) -> if (req.user is undefined) -> req.user = { id: 'public' } id = req.user.id // here i need to normalize the route in order to ignore routes with parameters routeParts = req.path.split('/') for each part in routeParths if (part matches an id format) -> replace it with (':param' + counter) routeParts.join('/') // this will convert a route /books/abc123 to /books/:param1 // now actually do the acl check node_acl.isAllowed(id, routeParts, request.method, func(err, isAllowed) -> if(isAllowed) -> next(); else response.notAllowed
译者注:这个例子还是不够完整,作者又给了一个完整的例子 https://github.com/icompuiz/express-mongoose-acl/commit/e27ef6c2bd61623f44849fd676d38bb289bc07eb
- node_acl用法示例
- node权限控制模块node_acl的应用
- SetTimeOut方法用法示例
- JTable用法示例
- JTree用法示例
- HashMap用法 示例
- TreeMap用法 示例
- SetTimeOut方法用法示例
- sscanf用法示例
- HashMap用法 示例
- InputStreamReader的用法示例
- SetTimeOut方法用法示例
- SetTimeOut方法用法示例
- ModalPopupExtender用法示例
- HashMap用法 示例
- getAttribute,setAttribute用法示例
- sscanf 用法示例
- Vml的用法示例
- Linux
- POJ
- okhttp学习
- 南阳理工第五题
- U盘启动DOS
- node_acl用法示例
- 爬虫之广度优先&深度优先
- 工厂设计模式(匿名类)
- opencv3_java 图片的ROI的领域合成 AddRoi
- Retrofit学习
- 南阳理工第六题
- JavaScript<2.2>
- c++指向对象成员函数的指针
- LeetCode 563. Binary Tree Tilt