Skip to content

Instantly share code, notes, and snippets.

@zmts
Last active April 23, 2024 16:00
Show Gist options
  • Save zmts/6e385e5773c5fce08aa2114c7e2cb463 to your computer and use it in GitHub Desktop.
Save zmts/6e385e5773c5fce08aa2114c7e2cb463 to your computer and use it in GitHub Desktop.
Управление правами/ролями в Node.js приложениях (Permissions/ACL)

Управление правами/ролями в Node.js приложениях (Permissions/ACL)

Допустим у наc есть такой CRUD и мы хотим проверять права доступа к каждому екшену.

class PostsController extends BaseController {
  static get router () {
    router.get('/', actionRunner(actions.ListAction))
    router.get('/:id', actionRunner(actions.GetByIdAction))
    router.post('/', actionRunner(actions.CreateAction))
    router.patch('/', actionRunner(actions.UpdateAction))

    return router
  }
}

Для этого у каждого action есть свой accessTag.

class ListAction extends BaseAction {
  static get accessTag () {
    return 'posts:list'
  }

  static run (req, res, next) {
    // logic
  }
}

В permissions конфиге для каждой роли предоставляем необходиые права:

const roles = require('./roles')

const usersResource = [ // all users endpoint actions, except creation
  'users:list',
  'users:update',
  'users:get-by-id',
  'users:remove',
  'users:change-password',
  'user:get-posts-by-user-id',
  'users:send-email-confirm-token',
  'users:change-email'
]

module.exports = {
  [roles.superadmin]: [
    // [roles.superadmin] have all permissions
    // so we don't need to list it
    // just check [roles.superadmin] in access services
  ],

  [roles.admin]: [
    ...usersResource,
    'posts:all',
    'auth:logout'
  ],

  [roles.moderator]: [
    ...usersResource,
    'posts:all',
    'auth:logout'
  ],

  [roles.editor]: [
    ...usersResource,
    'posts:all',
    'auth:logout'
  ],

  [roles.user]: [
    ...usersResource,
    'posts:all',
    'auth:logout'
  ],

  [roles.anonymous]: [
    'users:list',
    'users:get-by-id',
    'users:create',
    'users:send-reset-email',
    'users:reset-password',
    'users:get-posts-by-user-id',
    'users:confirm-email',

    'auth:login',
    'auth:refresh-tokens',

    'posts:list',
    'posts:get-by-id'
  ]
}

И при каждом обращении к екшену сервис security смотрит в токен на роль и в соотвестии с ролью пропускает или запещает использование екшена.

Пример имплементации: https://github.com/zmts/supra-api-nodejs/blob/master/services/security/checkAccessByTagService.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment