Questa è la mia implementazione.Il codice è riutilizzabile per client e server. Io lo uso per il mio espresso/sito web angolare
- ridurre il codice duplicato, una migliore coerenza tra client/server
- vantaggio Bonus: sull'adattatore del cliente, possiamo semplicemente restituire true per concedere l'accesso massimo per testare la robustezza dei server di (dal momento che gli hacker e facilmente superare lato client limitare)
in app/sia/both.js
var accessList = {
//note: same name as controller's function name
assignEditor: 'assignEditor'
,adminPage: 'adminPage'
,editorPage: 'editorPage'
,profilePage: 'profilePage'
,createArticle: 'createArticle'
,updateArticle: 'updateArticle'
,deleteArticle: 'deleteArticle'
,undeleteArticle: 'undeleteArticle'
,banArticle: 'banArticle'
,unbanArticle: 'unbanArticle'
,createComment: 'createComment'
,updateComment: 'updateComment'
,deleteComment: 'deleteComment'
,undeleteComment: 'undeleteComment'
,banComment: 'banComment'
,unbanComment: 'unbanComment'
,updateProfile: 'updateProfile'
}
exports.accessList = accessList
var resourceList = {
//Note: same name as req.resource name
profile: 'profile'
,article: 'article'
,comment: 'comment'
}
exports.resourceList = resourceList
var roleList = {
admin: 'admin'
,editor: 'editor'
,entityCreator: 'entityCreator'
,profileOwner: 'profileOwner' //creator or profile owner
,normal: 'normal' //normal user, signed in
,visitor: 'visitor' //not signed in, not used, open pages are uncontrolled
}
var permissionList = {}
permissionList[accessList.assignEditor] = [roleList.admin]
permissionList[accessList.adminPage] = [roleList.admin]
permissionList[accessList.editorPage] = [roleList.admin, roleList.editor]
permissionList[accessList.profilePage] = [roleList.admin, roleList.editor, roleList.normal]
permissionList[accessList.createArticle] = [roleList.admin, roleList.editor, roleList.normal]
permissionList[accessList.updateArticle] = [roleList.admin, roleList.editor, roleList.entityCreator]
permissionList[accessList.deleteArticle] = [roleList.admin, roleList.editor, roleList.entityCreator]
permissionList[accessList.undeleteArticle] = [roleList.admin, roleList.editor, roleList.entityCreator]
permissionList[accessList.banArticle] = [roleList.admin, roleList.editor]
permissionList[accessList.unbanArticle] = [roleList.admin, roleList.editor]
permissionList[accessList.createComment] = [roleList.admin, roleList.editor, roleList.normal]
permissionList[accessList.updateComment] = [roleList.admin, roleList.editor, roleList.entityCreator]
permissionList[accessList.deleteComment] = [roleList.admin, roleList.editor, roleList.entityCreator]
permissionList[accessList.undeleteComment] = [roleList.admin, roleList.editor, roleList.entityCreator]
permissionList[accessList.banComment] = [roleList.admin, roleList.editor]
permissionList[accessList.unbanComment] = [roleList.admin, roleList.editor]
permissionList[accessList.updateProfile] = [roleList.admin, roleList.profileOwner]
var getRoles = function(access, resource, isAuthenticated, entity, user) {
var roles = [roleList.visitor]
if (isAuthenticated) {
roles = [roleList.normal]
if (user.username === 'admin')
roles = [roleList.admin]
else if (user.type === 'editor')
roles = [roleList.editor]
if (resource) {
if (resource === resourceList.profile) {
//Note: on server _id is a object, client _id is string, which does not have equals method
if (entity && entity._id.toString() === user._id.toString())
roles.push(roleList.profileOwner)
}
else if (resource === resourceList.article) {
if (entity && entity.statusMeta.createdBy._id.toString() === user._id.toString())
roles.push(roleList.entityCreator)
}
else if (resource === resourceList.comment) {
if (entity && entity.statusMeta.createdBy._id.toString() === user._id.toString())
roles.push(roleList.entityCreator)
}
}
}
return roles
}
exports.havePermission = function(access, resource, isAuthenticated, entity, user) {
var roles = getRoles(access, resource, isAuthenticated, entity, user)
//Note: we can implement black list here as well, like IP Ban
if (!permissionList[access])
return true
for (var i = 0; i < roles.length; i++) {
var role = roles[i]
if (permissionList[access].indexOf(role) !== -1)
return true
}
return false
}
Poi app/Server/helper.js (agire come adattatore
var both = require(dir.both + '/both.js')
exports.accessList = both.accessList
exports.resourceList = both.resourceList
exports.havePermission = function(access, resource, req) {
return both.havePermission(access, resource, req.isAuthenticated(), req[resource], req.user)
}
//todo: use this function in other places
exports.getPermissionError = function(message) {
var err = new Error(message || 'you do not have the permission')
err.status = 403
return err
}
exports.getAuthenticationError = function(message) {
var err = new Error(message || 'please sign in')
err.status = 401
return err
}
exports.requiresPermission = function(access, resource) {
return function(req, res, next) {
if (exports.havePermission(access, resource, req))
return next()
else {
if (!req.isAuthenticated())
return next(exports.getAuthenticationError())
else
return next(exports.getPermissionError())
}
}
}
su app/client/helper.js, funge anche da adattatore.
exports.accessList = both.accessList
exports.resourceList = both.resourceList
exports.havePermission = function(access, resource, userService, entity) {
//Note: In debugging, we can grant client helper all access, and test robustness of server
return both.havePermission(access, resource, userService.isAuthenticated(), entity, userService.user)
}
C'è un modo senza utilizzare le sessioni? – Foreever
Ho trovato una soluzione migliore a questo. Ora utilizzerò il middleware espresso per verificare le autorizzazioni degli utenti prima che la rotta venga resa. Peresempio 'app.get ('/ users', permissions.check ('leggere', 'utenti'), func() {});' Questo ware mezzo poi i controlli nei confronti di un oggetto di autorizzazioni di configurazione come: 'roles.superAdmin = { id: "superadmin", nome: "Super Admin", descrizione: "", risorsa: [ { id: 'post', permesso: [ 'creare', 'leggere ',' aggiorna ',' cancella ') } ] }; ' – tkiddle
ya, esattamente. Stavo arrivando a quel punto. Ma come stai seguendo l'utente? Inoltre, se hai la risposta, dovresti postarla qui per gli altri. – Foreever