{"id":341447,"date":"2022-11-18T15:01:15","date_gmt":"2022-11-18T15:01:15","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=341447"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=341447","title":{"rendered":"<span>\u0413\u043e\u0442\u043e\u0432\u0438\u043c, \u043f\u0440\u043e\u0431\u0443\u0435\u043c Casbin RBAC \u0438 handmade RBAC<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/292\/57d\/b21\/29257db21d52fc9abea9a70807bddd1a.jpg\" width=\"1560\" height=\"880\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/292\/57d\/b21\/29257db21d52fc9abea9a70807bddd1a.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442!<\/p>\n<p>\u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0410\u043d\u0434\u0440\u0435\u0439 \u0422\u0430\u0431\u043e\u043b\u0438\u043d, \u044f \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a \u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Bimeister.<\/p>\n<p><a href=\"https:\/\/casbin.org\/\">Casbin<\/a>\u00a0\u2013\u00a0\u043e\u0434\u043d\u0430 \u0438\u0437 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043b Casbin, \u043f\u043e\u043f\u0443\u0442\u043d\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b \u0441\u0432\u043e\u0451 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0438\u00a0\u043f\u043e\u043a\u0430\u0436\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u0431\u043e\u0438\u0445. \u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0430\u0441\u044c \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c\u00a0\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0421\u0423\u0411\u0414 \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u043e\u0431\u044a\u0451\u043c\u0430\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0440\u043e\u043b\u0435\u0432\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 (RBAC).\u00a0\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b: Node.js + PostgreSQL.<\/p>\n<h2>\u041f\u0435\u0440\u0435\u0434 \u0441\u0442\u0430\u0440\u0442\u043e\u043c<\/h2>\n<p>\u0414\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0443\u0436\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u0445\u043e\u0442\u044f \u0431\u044b \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 RBAC \u0438 PERM.<\/p>\n<p>RBAC (<em>Role-Based Access Control<\/em>)\u00a0\u2013\u00a0\u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043d\u0430\u0434 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0440\u043e\u043b\u0438 \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0415\u0441\u0442\u044c \u0435\u0449\u0451 ABAC\u00a0\u2013\u00a0\u043c\u043e\u0434\u0435\u043b\u044c, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0430\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b. \u0418 \u0434\u0440\u0443\u0433\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u043a\u0430\u0441\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u043c. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435:\u00a0<a href=\"https:\/\/habr.com\/ru\/company\/custis\/blog\/248649\/\">\u041f\u043e\u0434\u0445\u043e\u0434\u044b \u043a \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044e \u0434\u043e\u0441\u0442\u0443\u043f\u0430: RBAC vs. ABAC<\/a>.<\/p>\n<p>PERM\u00a0(<em>Policy, Effect, Request, Matchers<\/em>) \u2013\u00a0\u043c\u0435\u0442\u0430\u043c\u043e\u0434\u0435\u043b\u044c \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0446\u0435\u043b\u0435\u0432\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430. \u0421 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c: RBAC, ABAC, ACL \u0438 \u0434\u0440. \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 (<em>*.conf<\/em>), \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u043c \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b Casbin. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/post\/539778\/\">RBAC? ABAC?.. PERM! \u041d\u043e\u0432\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u0432\u0435\u0431-\u0441\u043b\u0443\u0436\u0431\u0430\u0445 \u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445<\/a><\/p>\n<\/li>\n<li>\n<p>Casbin:\u00a0<a href=\"https:\/\/casbin.org\/docs\/en\/how-it-works\">How it Works<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/casbin.org\/en\/editor\">\u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440<\/a>\u00a0Casbin \u0434\u043b\u044f \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f PERM<\/p>\n<\/li>\n<\/ul>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/h2>\n<h3>\u0422\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445<\/h3>\n<p>\u042f \u0440\u0435\u0448\u0438\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u00a0\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435:<\/p>\n<ul>\n<li>\n<p>\u041e\u0431\u044a\u0435\u043a\u0442\u044b,\u00a0\u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0434\u043e\u0441\u0442\u0443\u043f<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0434 \u043d\u0438\u043c\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439<\/p>\n<\/li>\n<li>\n<p>\u0420\u043e\u043b\u0438 \u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0432 \u043d\u0438\u0445 \u0432 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0440\u043e\u043b\u0435\u0439 \u043f\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u0431\u044a\u0435\u043a\u0442 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u044c\u0441\u044f\u00a0\u043a \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435 (<em>Group<\/em>) \u0438 \u0442\u0438\u043f\u0443 (<em>Type<\/em>). \u041f\u043e\u0434 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u0432\u043e\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0432\u0438\u0434\u0430: Group1Type1.<br \/>\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043b \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 CRUD (<em>Create Read Update Delete<\/em>) \u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b \u043f\u043e \u043d\u0438\u043c \u0440\u043e\u043b\u0438 \u0441 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438.<br \/>\u0418\u0442\u043e\u0433\u043e, \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043d\u0430\u0431\u043e\u0440\u0435 (<em>Group Set<\/em>) \u0431\u0443\u0434\u0435\u0442\u00a02 \u0433\u0440\u0443\u043f\u043f\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432,\u00a0\u043f\u043e 4 \u0442\u0438\u043f\u0430 \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435,\u00a0\u043f\u043e 4 \u0440\u043e\u043b\u0438 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0438\u043f:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d51\/af6\/443\/d51af644343046737328d2c26ef3a32a.png\" width=\"967\" height=\"623\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d51\/af6\/443\/d51af644343046737328d2c26ef3a32a.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043b \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043e\u0447\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0451\u043c\u0430 \u0434\u043b\u044f \u0440\u043e\u043b\u0435\u0432\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b \u0433\u0440\u0443\u043f\u043f\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 (<em>User Gr<\/em>), \u043d\u0430\u0437\u043d\u0430\u0447\u0438\u043b \u0438\u043c \u0440\u043e\u043b\u0438. \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u043e\u043b\u0435\u0439 \u043d\u0430 \u0433\u0440\u0443\u043f\u043f\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f, \u043e\u0434\u0438\u043d \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0433\u0440\u0443\u043f\u043f\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043b\u0430\u0434\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0440\u043e\u043b\u044f\u043c\u0438.<\/p>\n<p>\u0418\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430\u0437\u0432\u0430\u043b \u043f\u0443\u043b (<em>Pool<\/em>), \u043e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442:<\/p>\n<ul>\n<li>\n<p>32 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0442\u0438\u043f\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 = 32 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u043f\u043e 10 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432 \u043a\u0430\u0436\u0434\u043e\u0439. \u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u043e\u043b\u0435\u0432\u043e\u0439 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>16 \u0440\u043e\u043b\u0435\u0439, \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0445 \u043c\u0435\u0436\u0434\u0443 1000 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0435 \u043f\u0443\u043b\u0430 \u0437\u0430\u043b\u043e\u0436\u0438\u043b \u043c\u043d\u043e\u0436\u0438\u0442\u0435\u043b\u044c. \u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u043e\u0431\u044a\u0451\u043c\u0430\u0445: 1 \u043f\u0443\u043b, 2 \u043f\u0443\u043b\u0430 \u0438\u043b\u0438 10.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b72\/ce7\/80f\/b72ce780f4ad26a124a8ae0df0eceeb8.png\" width=\"1132\" height=\"525\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b72\/ce7\/80f\/b72ce780f4ad26a124a8ae0df0eceeb8.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f RBAC \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430.<\/p>\n<h3>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439<\/h3>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 RBAC \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0434\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438\u00a0\u2013\u00a0\u0447\u0442\u0435\u043d\u0438\u0435. \u041c\u043d\u0435 \u0432\u0430\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f: \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043d\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0438\u043b\u0438 \u043d\u0435\u0442.<\/p>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u043e\u0432 \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0443\u044e\u00a0<a href=\"https:\/\/github.com\/Qxor\/casbin-cli-prototype\">\u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u0443\u044e \u0443\u0442\u0438\u043b\u0438\u0442\u0443 (CLI)<\/a>,\u00a0\u0442\u0430\u043a \u0431\u044b\u043b\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0431\u0443\u0434\u0443\u0442 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c \u0441\u0442\u0438\u043b\u0435:<\/p>\n<ul>\n<li>\n<p>\u0445\u043e\u0447\u0443 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0438 \u0442\u0438\u043f\u0430:\u00a0<em>list obj group=1 type=1<\/em><\/p>\n<\/li>\n<li>\n<p>\u0445\u043e\u0447\u0443 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043c\u043d\u0435 \u0442\u0438\u043f\u043e\u0432 \u0438\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b: <em>list obj group=1<\/em><\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430. \u0412 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b, \u043a\u0430\u043a \u0431\u044b\u0441\u0442\u0440\u043e \u0440\u043e\u043b\u0435\u0432\u0430\u044f:<\/p>\n<ul>\n<li>\n<p><em>group, type<\/em>\u00a0\u2013\u00a0\u043f\u0440\u0438\u043c\u0435\u0442 \u0440\u0435\u0448\u0435\u043d\u0438\u0435: \u0438\u043c\u0435\u044e \u044f \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435 \u0438 \u0442\u0438\u043f\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432<\/p>\n<\/li>\n<li>\n<p><em>group<\/em>\u00a0\u2013\u00a0\u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0438\u043f \u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b, \u0432 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0443 \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u044b CLI \u043e\u0442\u0440\u0430\u0436\u0430\u044e\u0442 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0435 \u043a\u0435\u0439\u0441\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:<\/p>\n<ul>\n<li>\n<p>\u0437\u0430\u0448\u0451\u043b \u0432 \u0440\u0430\u0437\u0434\u0435\u043b \u0438 \u0432\u0438\u0436\u0443\/\u043d\u0435 \u0432\u0438\u0436\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u044b<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u0448\u0451\u043b \u0432 \u0440\u0430\u0437\u0434\u0435\u043b \u0438 \u0432\u0438\u0436\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432<\/p>\n<\/li>\n<\/ul>\n<h3>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 Casbin<\/h3>\n<p>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b \u0441\u0430\u043c\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 Casbin \u043f\u043e\u00a0<a href=\"https:\/\/casbin.org\/docs\/en\/get-started\">\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438<\/a>\u00a0\u043e\u0442 \u0430\u0432\u0442\u043e\u0440\u043e\u0432 \u0434\u043b\u044f Node.js.\u00a0<\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0421\u0423\u0411\u0414\u00a0Casbin \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u00a0<a href=\"https:\/\/casbin.org\/docs\/en\/adapters\">\u0430\u0434\u0430\u043f\u0442\u0435\u0440\u044b<\/a>\u00a0\u043a\u0430\u043a\u00a0middleware. \u0412\u044b\u0431\u043e\u0440 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u044f\u0437\u044b\u043a\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0441\u0430\u043c\u043e\u0433\u043e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u043e\u0434 \u043c\u043e\u0439 \u0441\u0442\u0435\u043a \u0438 \u0437\u0430\u0434\u0430\u0447\u0443 \u0432\u0437\u044f\u043b\u00a0<a href=\"https:\/\/github.com\/node-casbin\/sequelize-adapter\">Sequelize Adapter<\/a>. \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043c\u043d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u00a0<a href=\"https:\/\/node-postgres.com\/\">pg<\/a>\u00a0\u0434\u043b\u044f PostgreSQL\u00a0\u2013\u00a0\u0432\u044b\u0434\u0430\u0432\u0430\u043b\u043e \u043e\u0448\u0438\u0431\u043a\u0443 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435. \u0414\u0440\u0430\u0439\u0432\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u0438\u043c Sequelize Adapter.<\/p>\n<p>\u0423 Casbin \u0435\u0441\u0442\u044c\u00a0<a href=\"https:\/\/casbin.org\/docs\/en\/policy-storage#database-storage-format\">\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u0442\u0430\u0431\u043b\u0438\u0446\u0435<\/a>, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u044b \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441\u0430\u043c\u0438 \u043f\u043e-\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e. \u041d\u043e \u0441 \u043c\u043e\u0438\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u044f\u0432\u043d\u043e, \u0441\u0442\u0440\u043e\u0433\u043e \u0441 \u0438\u043c\u0435\u043d\u0435\u043c\u00a0\u00abcasbin_rule\u00bb\u00a0\u0438 \u043f\u043e\u043b\u044f\u043c\u0438 \u043d\u0438\u0436\u0435. \u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u043a\u043b\u044e\u0447. Casbin \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430\u043c\u0438, \u043d\u043e\u00a0\u043d\u0435 \u0441 id\u00a0\u0437\u0430\u043f\u0438\u0441\u0435\u0439. \u0421\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430 \u0438\u043b\u0438 \u0440\u0443\u043a\u0430\u043c\u0438. \u042f \u0441\u043e\u0437\u0434\u0430\u043b \u0440\u0443\u043a\u0430\u043c\u0438 \u0432 \u0421\u0423\u0411\u0414.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\"><strong>\u041f\u043e\u043b\u0435<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\">id<\/p>\n<\/td>\n<td>\n<p align=\"left\">serial,\u00a0Primary Key  <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\">ptype<\/p>\n<\/td>\n<td>\n<p align=\"left\">varchar 255, null  <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\">v0<\/p>\n<\/td>\n<td>\n<p align=\"left\">varchar 255, null  <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\">v1<\/p>\n<\/td>\n<td>\n<p align=\"left\">varchar 255, null  <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\">v2<\/p>\n<\/td>\n<td>\n<p align=\"left\">varchar 255, null  <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\">v3<\/p>\n<\/td>\n<td>\n<p align=\"left\">varchar 255, null  <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\">v4<\/p>\n<\/td>\n<td>\n<p align=\"left\">varchar 255, null  <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\">v5<\/p>\n<\/td>\n<td>\n<p align=\"left\">varchar 255, null  <\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0418\u043d\u0444\u043e \u043f\u043e \u043f\u043e\u043b\u044f\u043c:<\/p>\n<ul>\n<li>\n<p><em>id<\/em>\u00a0\u2013\u00a0\u0438\u0434 \u0437\u0430\u043f\u0438\u0441\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b<\/p>\n<\/li>\n<li>\n<p><em>ptype<\/em>\u00a0\u2013\u00a0\u0442\u0438\u043f \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 Casbin<\/p>\n<\/li>\n<li>\n<p><em>v0 &#8212; v5<\/em>\u00a0\u2013\u00a0\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 [policy_definition] \u0444\u0430\u0439\u043b\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Casbin<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u043b \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u044e\u00a0<a href=\"https:\/\/casbin.org\/docs\/en\/adapters#how-to-write-an-adapter\">\u043f\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438<\/a>.<\/p>\n<p>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b \u0444\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Casbin (<em>.conf<\/em>):<\/p>\n<pre><code>[request_definition] r = sub, objGroup, objType, act   [policy_definition] p = sub, objGroup, objType, act   [role_definition] g = _, _   [policy_effect] e = some(where (p.eft == allow))   [matchers] m = g(r.sub, p.sub) &amp;&amp; r.objGroup == p.objGroup &amp;&amp; r.objType == p.objType &amp;&amp; r.act == p.act<\/code><\/pre>\n<p>\u0423 \u043c\u0435\u043d\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043c\u0430\u043f\u043f\u0438\u043d\u0433 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0444\u0430\u0439\u043b\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Casbin \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435\u0439\u00a0<em>casbin_rule<\/em>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9ff\/bd1\/513\/9ffbd151330d1d834ac7358ae5802f40.png\" width=\"1198\" height=\"520\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9ff\/bd1\/513\/9ffbd151330d1d834ac7358ae5802f40.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412\u00a0\u00abcasbin_rule\u00bb\u00a0\u0432\u043d\u0451\u0441 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u044b Casbin \u0441 \u0421\u0423\u0411\u0414. \u0412\u044b\u0432\u0435\u043b \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u00a0\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u043f\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0443, \u0443\u043a\u0430\u0437\u0430\u0432: \u0440\u043e\u043b\u044c, \u0433\u0440\u0443\u043f\u043f\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u0438\u0445 \u0442\u0438\u043f.<\/p>\n<pre><code class=\"javascript\">import { newEnforcer } from \"casbin\"; import { SequelizeAdapter } from \"casbin-sequelize-adapter\";   const app = async () => {   \/\/\u0433\u043e\u0442\u043e\u0432\u0438\u043c \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0434\u043b\u044f \u0421\u0423\u0411\u0414   const adapter = await SequelizeAdapter.newAdapter({     username: \"postgres\",     password: \"password\",     database: \"casbin\",     dialect: \"postgresql\",     logging: false,  \/\/\u0432\u044b\u043a\u043b\u044e\u0447\u0438\u043b\u0438 \u043b\u043e\u0433\u0438 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c, \u043c\u0435\u0448\u0430\u044e\u0442   });         \/\/\u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043e\u0431\u044a\u0435\u043a\u0442 casbin, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430\u043c\u0438,   \/\/\u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0438 \u0430\u0434\u0430\u043f\u0442\u0435\u0440   const e = await newEnforcer(\".\/rbac_model.conf\", adapter);     \/\/\u0447\u0435\u0440\u0435\u0437 API \u043e\u0431\u044a\u0435\u043a\u0442\u0430 casbin \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u043f\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0443, \u043f\u0435\u0440\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 - \u043d\u043e\u043c\u0435\u0440 \u043f\u043e\u043b\u044f v*   \/\/v0 == \"role1\", v1 == \"group1\", v2 == \"type1\"   const rules = await e.getFilteredPolicy(0, \"role1\", \"group1\", \"type1\");     \/\/\u0437\u0430\u043a\u0440\u043e\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0421\u0423\u0411\u0414   await adapter.close();   console.log(rules); };   app() \/\/\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f: [ [ 'role1', 'group1', 'type1', 'read' ] ]<\/code><\/pre>\n<p>\u0421\u0443\u043f\u0435\u0440, \u0434\u043e\u0440\u043e\u0433\u0443 \u043a \u0421\u0423\u0411\u0414\u00a0\u0447\u0435\u0440\u0435\u0437 Casbin \u043f\u0440\u043e\u043b\u043e\u0436\u0438\u043b. \u0414\u0430\u043b\u044c\u0448\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435.<\/p>\n<h3>\u0425\u0440\u0430\u043d\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0420\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u0431\u0443\u0434\u0443 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0432\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0440\u043e\u043b\u0435\u0432\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438: Casbin \u0438 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u0443\u044e (<em>handmade<\/em>) \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432 \u0411\u0414:<\/p>\n<ul>\n<li>\n<p>Users &#8212; \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438<\/p>\n<\/li>\n<li>\n<p>Auth &#8212; \u043b\u043e\u0433\u0438\u043d\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439<\/p>\n<\/li>\n<li>\n<p>Roles &#8212; \u0440\u043e\u043b\u0438<\/p>\n<\/li>\n<li>\n<p>Permissions &#8212; \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430. \u041e\u0434\u043d\u0430 \u0440\u043e\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 (<em>permissions<\/em>) \u0432 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u043b\u0438 \u043c\u043d\u043e\u0433\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>UserRoles &#8212; \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u043d\u0438\u0445 \u0440\u043e\u043b\u0438<\/p>\n<\/li>\n<li>\n<p>casbin_rule &#8212; \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0434\u043b\u044f Casbin, \u043e\u0431\u0441\u0443\u0434\u0438\u043b\u0438 \u0432\u044b\u0448\u0435 \u0438 \u0443\u0436\u0435 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438<\/p>\n<\/li>\n<li>\n<p>Objects* &#8212; \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0434\u043b\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u0443\u043b\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c37\/99a\/eb6\/c3799aeb61ed3331d6de9c163a5db721.png\" width=\"1781\" height=\"797\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c37\/99a\/eb6\/c3799aeb61ed3331d6de9c163a5db721.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043f\u0430\u0440\u044b \u0442\u0430\u0431\u043b\u0438\u0446. \u0412 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u043e \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0435 \u0411\u0414, \u0434\u0443\u043c\u0430\u044e, \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e.\u00a0<\/p>\n<p><em>\u0442\u0430\u0431\u043b.\u00a0\u00abcasbin_rule\u00bb<\/em><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>id<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>ptype<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>v0<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>v1<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>v2<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>v3<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>v4<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>v5<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">1<\/p>\n<\/td>\n<td>\n<p align=\"left\">p<\/p>\n<\/td>\n<td>\n<p align=\"left\">role1<\/p>\n<\/td>\n<td>\n<p align=\"left\">group1<\/p>\n<\/td>\n<td>\n<p align=\"left\">type1<\/p>\n<\/td>\n<td>\n<p align=\"left\">read<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">2<\/p>\n<\/td>\n<td>\n<p align=\"left\">p<\/p>\n<\/td>\n<td>\n<p align=\"left\">role2<\/p>\n<\/td>\n<td>\n<p align=\"left\">group2<\/p>\n<\/td>\n<td>\n<p align=\"left\">type2<\/p>\n<\/td>\n<td>\n<p align=\"left\">read<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">3<\/p>\n<\/td>\n<td>\n<p align=\"left\">p<\/p>\n<\/td>\n<td>\n<p align=\"left\">role2<\/p>\n<\/td>\n<td>\n<p align=\"left\">group2<\/p>\n<\/td>\n<td>\n<p align=\"left\">type2<\/p>\n<\/td>\n<td>\n<p align=\"left\">create<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><em>\u0442\u0430\u0431\u043b. \u00abPermissions\u00bb<\/em>  <\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>Id<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>RoleId<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>ObjectGroup<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>ObjectType<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>Permission<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">1<\/p>\n<\/td>\n<td>\n<p align=\"left\">1<\/p>\n<\/td>\n<td>\n<p align=\"left\">group1<\/p>\n<\/td>\n<td>\n<p align=\"left\">type1<\/p>\n<\/td>\n<td>\n<p align=\"left\">read<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">2<\/p>\n<\/td>\n<td>\n<p align=\"left\">2<\/p>\n<\/td>\n<td>\n<p align=\"left\">group2<\/p>\n<\/td>\n<td>\n<p align=\"left\">type2<\/p>\n<\/td>\n<td>\n<p align=\"left\">read<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">3<\/p>\n<\/td>\n<td>\n<p align=\"left\">2<\/p>\n<\/td>\n<td>\n<p align=\"left\">group2<\/p>\n<\/td>\n<td>\n<p align=\"left\">type2<\/p>\n<\/td>\n<td>\n<p align=\"left\">create<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430\u00a0\u0444\u0443\u043d\u043a\u0446\u0438\u0439<\/h2>\n<h3>\u041a\u043e\u043c\u0430\u043d\u0434\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/h3>\n<p>\u041e\u0431\u0449\u0438\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0439 CLI \u043f\u0440\u043e\u0441\u0442 \u0438 \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438: handmade \u0438\u043b\u0438 \u0421asbin. \u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u043c\u0430\u043d\u0434\u044b\u00a0<em>list obj<\/em>\u00a0\u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bef\/872\/a7d\/bef872a7d9d938898d93cec5f3d7be9b.png\" width=\"778\" height=\"375\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bef\/872\/a7d\/bef872a7d9d938898d93cec5f3d7be9b.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0418\u0437 \u0441\u0445\u0435\u043c\u044b \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f CLI \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c:<\/p>\n<ul>\n<li>\n<p><strong>\u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440<\/strong>\u00a0\u2013\u00a0\u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0430\u044f \u0434\u043e\u0441\u0442\u0443\u043f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443. \u0412\u0437\u044f\u043b \u0438\u0437 \u0442\u0435\u0440\u043c\u0438\u043d\u043e\u043b\u043e\u0433\u0438\u0438 Casbin \u0434\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0411\u0414<\/p>\n<\/li>\n<\/ul>\n<p>\u0417\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"javascript\">async someCliFunc(user, obj, act) {   \/\/\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438   const allowed = await enforce(user, obj, act);       \/\/\u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043e, \u0442\u043e \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435. \u0415\u0441\u043b\u0438 \u043d\u0435\u0442, \u0442\u043e \u043e\u0442\u043a\u0430\u0437   if (allowed) {     const objects = await this.db.listObjects();     return objects;   } else {     return this.denyMessage;   } }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u0448\u0451\u043b \u043a \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0435\u00a0\u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439\u00a0<em>enforce.<\/em><\/p>\n<h4>Handmade \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440<\/h4>\n<p>\u0414\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u0441\u0445\u0435\u043c\u044b \u0411\u0414 \u043c\u043d\u0435 \u0431\u044b\u043b\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"javascript\">\/\/db - \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 DB \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0421\u0423\u0411\u0414, \/\/\u0432 \u043d\u0451\u043c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u044b \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b const enforce = async (db, user, group, type, act) => {       \/\/\u0437\u0430\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b Permissions \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0443   const permissions = await db.getUserPermissions(user, group, type, act);     \/\/\u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u044c \u043e\u0434\u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c \u0435\u0441\u0442\u044c, \u0442\u043e \u0434\u043e\u0441\u0442\u0443\u043f \u0440\u0430\u0437\u0440\u0435\u0448\u0451\u043d   return permissions.length > 0; }<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0411\u0414 (<em>db<\/em>) \u0432\u044b\u043d\u0435\u0441 \u0437\u0430 \u0440\u0430\u043c\u043a\u0438 \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430, \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u043e \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438. \u041e\u0434\u0438\u043d \u0440\u0430\u0437 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0438 \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f. \u041d\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435\u00a0<em>Permissions<\/em>\u00a0\u0432 \u043c\u043e\u0435\u0439 \u0441\u0445\u0435\u043c\u0435 \u043d\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041d\u043e \u0442.\u043a. \u044f \u0433\u043e\u0442\u043e\u0432\u0438\u043b handmade, \u0442\u043e \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0437\u0430\u043f\u0440\u0435\u0449\u0430\u043b \u043c\u043d\u0435 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435\u00a0<em>db.getUserPermissions<\/em>\u00a0\u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c sql-\u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u0438\u0434\u0430:<\/p>\n<pre><code class=\"sql\">with rolesId as (       select userRoles.\"RoleId\" from public.\"UserRoles\" as userRoles       inner join public.\"Auth\" as auth       on auth.\"UserId\" = userRoles.\"UserId\"       where auth.\"Login\"='${user}'     )                 select * from public.\"Permissions\" as perm inner join rolesId on rolesId.\"RoleId\" = perm.\"RoleId\" where perm.\"ObjectGroup\"='${group}'   and perm.\"ObjectType\"='${type}'   and perm.\"Permission\"='${act}'<\/code><\/pre>\n<p>\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 \u0438\u043d\u043b\u0430\u0439\u043d SQL-\u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f ORM. \u0412 \u043c\u043e\u0451\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0442 \u0436\u0435 Sequelize. \u0414\u043b\u044f \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044f \u0444\u043e\u043d\u043e\u043c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e handmade \u043d\u0430 \u043d\u0451\u043c.  <\/p>\n<h4>Casbin \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440<\/h4>\n<p>\u041d\u0430 \u0441\u0430\u0439\u0442\u0435 Casbin \u0435\u0441\u0442\u044c\u00a0<a href=\"https:\/\/casbin.org\/docs\/en\/get-started\">\u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430<\/a>.<\/p>\n<p>\u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044f \u043f\u043e\u0448\u0451\u043b\u00a0\u0441\u0445\u043e\u0436\u0438\u043c \u0441 handmade \u043f\u0443\u0442\u0451\u043c\u00a0\u2013\u00a0\u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440.\u00a0\u0424\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0421asbin \u0438 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u043a \u0411\u0414 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0441 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435. \u041c\u043e\u0449\u043d\u043e, \u043a\u0440\u0443\u0442\u043e.<\/p>\n<pre><code class=\"javascript\">const enforce = async (model, adapter, ...args) => {   const e = await casbin.newEnforcer(model, adapter);      \/\/\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 Casbin-\u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440   const allowed = await e.enforce(...args);     await adapter.close();   return allowed; };<\/code><\/pre>\n<p>\u041d\u043e \u0440\u0430\u0434\u043e\u0441\u0442\u044c \u043c\u043e\u044f \u0431\u044b\u0441\u0442\u0440\u043e \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0430\u0441\u044c, \u043a\u043e\u0433\u0434\u0430 \u044f \u043d\u0430\u0447\u0430\u043b \u0434\u0435\u043b\u0430\u0442\u044c \u0437\u0430\u043c\u0435\u0440\u044b \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0431\u044b\u043b\u0438 \u043d\u0435\u0443\u0442\u0435\u0448\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435.<\/p>\n<p>\u0412 \u0445\u043e\u0434\u0435 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432 \u0432\u044b\u044f\u0441\u043d\u0438\u043b, \u0447\u0442\u043e\u00a0<em>casbin.newEnforcer<\/em>\u00a0\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0432\u0441\u0435 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u0438\u0437 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0432 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u044f \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435 \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430 \u043f\u0440\u043e\u0441\u0438\u043b Casbin \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432\u0441\u0451 \u0438\u0437 \u0411\u0414 \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043a \u0441\u0435\u0431\u0435. \u041d\u0435\u0443\u0434\u0438\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u0447\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043c\u0435\u043d\u044f \u043e\u043f\u0435\u0447\u0430\u043b\u0438\u043b\u0438. \u041f\u043e\u043d\u044f\u0432 \u043f\u0440\u0438\u0440\u043e\u0434\u0443 Casbin, \u044f \u0432\u044b\u043d\u0435\u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 CLI.\u00a0\u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043c\u043d\u0435 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"javascript\">const allowed = await e.enforce(user, group, type, act)<\/code><\/pre>\n<p>\u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0411\u0414 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c? \u0415\u0441\u043b\u0438 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u0432 \u043e\u0431\u0449\u0435\u043c, \u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430\u043c\u0438 \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437\u00a0<a href=\"https:\/\/casbin.org\/docs\/en\/management-api\">API \u0441\u0430\u043c\u043e\u0433\u043e \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430 Casbin<\/a>. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u0432 \u0411\u0414 \u0431\u044b\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b \u043d\u0435 \u0447\u0435\u0440\u0435\u0437 \u043d\u0430\u0448 \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e\u00a0<a href=\"https:\/\/casbin.org\/docs\/en\/policy-storage#adapter-api\">LoadPolicy<\/a>.  <\/p>\n<h3>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/h3>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u043e\u0432 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:<\/p>\n<ul>\n<li>\n<p>list obj group={n} type={m}\u00a0\u2013\u00a0\u043f\u043e\u043a\u0430\u0436\u0438 \u0432\u0441\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0433\u0440\u0443\u043f\u043f\u044b N \u0442\u0438\u043f\u0430 M<\/p>\n<\/li>\n<li>\n<p>list obj group={n}\u00a0\u2013\u00a0\u043f\u043e\u043a\u0430\u0436\u0438 \u0432\u0441\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0433\u0440\u0443\u043f\u043f\u044b N<\/p>\n<\/li>\n<\/ul>\n<h4>list obj group={n} type={m}<\/h4>\n<p><strong>Handmade<\/strong><\/p>\n<p>\u0418\u043d\u0444\u043e\u0440\u0441\u0435\u0440 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043b \u0432\u00a0\u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b:<\/p>\n<pre><code class=\"javascript\">const enforce = async (db, user, group, type, act) => {   const permissions = await db.getUserPermissions(user, group, type, act);   return permissions.length > 0; }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u0435\u0433\u043e \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 CLI:  <\/p>\n<pre><code class=\"javascript\">import enforce from 'handmadeEnforcer.js'   async listObjectsByType(group, type) {   \/\/\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0411\u0414 (this.db) \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 CLI   const allowed = await enforce(this.db, this.userLogin, group, type, \"read\");       if (allowed) {     const objects = await this.db.listObjectsByType(group, type);     return objects;   } else {     return this.denyMessage;   } }<\/code><\/pre>\n<p><strong>Casbin<\/strong><\/p>\n<p>\u0412 \u043a\u043b\u0430\u0441\u0441\u0435 CLI \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b \u043c\u0435\u0442\u043e\u0434\u00a0<em>init<\/em>\u00a0\u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430:<\/p>\n<pre><code class=\"javascript\">import { newEnforcer } from \"casbin\"; import { SequelizeAdapter } from \"casbin-sequelize-adapter\";   async init() {   const adapter = await SequelizeAdapter.newAdapter({     username: \"postgres\",     password: \"password\",     database: \"casbin\",     dialect: \"postgresql\",     logging: false   });     const model = \".\/rbac_model.conf\";   this.enforcer = await newEnforcer(model, adapter); }<\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043b \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440 Casbin \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:<\/p>\n<pre><code class=\"javascript\">async listObjectsByType(group, type) {   const allowed = await this.enforcer.enforce(this.userLogin, group, type, \"read\");     if (allowed) {     const objects = await this.db.listObjectsByType(group, type);     return objects;   } else {     return this.denyMessage;   } }<\/code><\/pre>\n<h4>list obj group={n}<\/h4>\n<p><strong>Handmade<\/strong><\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043b\u043e\u0433\u0438\u043a\u0430 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f. \u0412\u0441\u0435\u0433\u043e 4 \u0442\u0438\u043f\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432 \u043e\u0434\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435, \u0430 \u0434\u043e\u0441\u0442\u0443\u043f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u0434\u0432\u0443\u043c, \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443. \u042d\u0442\u0438 \u0434\u0432\u0430 \u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e.<\/p>\n<p>\u0423\u0432\u0438\u0434\u0435\u043b \u043f\u0430\u0440\u0443 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438:<\/p>\n<ol>\n<li>\n<p>\u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0442\u0438\u043f\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0438\u043f \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440. \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0443 \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0438 \u0437\u0430\u043f\u0440\u043e\u0448\u0443 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u043d\u0435\u043c\u0443<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u0411\u0414\u00a0<em>getUserPermissions<\/em>, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043c\u043e\u0433 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043f\u0443\u0441\u0442\u043e\u0439 \u0442\u0438\u043f \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0432\u0441\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u043f\u043e \u0433\u0440\u0443\u043f\u043f\u0435<\/p>\n<\/li>\n<\/ol>\n<p>\u0420\u0435\u0448\u0438\u043b \u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0440\u0430\u0434\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0430 \u0432 \u043f.2. \u041e\u0431\u0435\u0440\u043d\u0443\u043b \u0435\u0433\u043e \u043d\u0435 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e\u00a0<em>enforce<\/em>, \u0430 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e\u00a0<em>getAllowedTypes<\/em>:<\/p>\n<pre><code class=\"javascript\">const getAllowedTypes = async (db, user, group, act) => {   \/\/\u0442\u0435\u043f\u0435\u0440\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438 \u043c\u043e\u0436\u043d\u043e \u0431\u0435\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0442\u0438\u043f\u0430   const permissions = await db.getUserPermissions({user, group, act});    \/\/\u0432\u0435\u0440\u043d\u0451\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u0430\u0441\u0441\u0438\u0432 \u0442\u0438\u043f\u043e\u0432   return permissions.map((rec) => rec.ObjectType); }<\/code><\/pre>\n<p>\u041a\u043e\u0434 \u0432 CLI:<\/p>\n<pre><code class=\"javascript\">import { getAllowedTypes } from 'handmadeEnforcer.js'   async listObjectsByGroup(group) {   const allowedTypes = await getAllowedTypes(this.db, this.userLogin, group, \"read\");     \/\/\u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u044b\u0431\u043e\u0440\u043a\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438\u0437 \u0411\u0414 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e   if (allowedTypes.length > 0) {     const objects = await Promise.all(       allowedTypes.map(async (type) => await this.db.listObjectsByType(group, type))     )     return objects.flat();   } else {     return this.denyMessage   } }<\/code><\/pre>\n<p><strong>Casbin<\/strong><\/p>\n<p>\u0421 Casbin \u0442\u0440\u044e\u043a \u043f\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0442\u043e\u0436\u0435 \u043f\u0440\u043e\u0439\u0434\u0451\u0442. \u042f \u0443\u0436\u0435 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u043b \u043f\u043e\u0445\u043e\u0436\u0438\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e\u00a0<a href=\"https:\/\/casbin.org\/docs\/en\/management-api#getfilteredpolicy\">e.getFilteredPolicy<\/a>.<\/p>\n<p>\u041d\u043e \u0442\u0430\u043a\u0430\u044f \u043a\u0430\u0440\u0435\u0442\u0430 \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u0441\u044f \u0432 \u0442\u044b\u043a\u0432\u0443, \u043a\u043e\u0433\u0434\u0430 \u044f \u0437\u0430\u0445\u043e\u0447\u0443 \u0443\u0441\u043b\u043e\u0436\u043d\u0438\u0442\u044c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0437\u0430 \u0441\u0447\u0451\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0438\u043b\u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430\u0445 \u043c\u0430\u0441\u043e\u043a\/\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0435\u0439:<\/p>\n<ul>\n<li>\n<p>group*<\/p>\n<\/li>\n<li>\n<p>type[1-10]<\/p>\n<\/li>\n<li>\n<p>!delete<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440.<\/p>\n<\/li>\n<\/ul>\n<p><em>\u0421\u043f\u043e\u0439\u043b\u0435\u0440:\u00a0<\/em>\u0432 Casbin \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435\u00a0<em>e.enforce()<\/em>\u00a0\u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0442\u0430\u043a\u0438\u043c\u0438 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u043c\u0438\u00a0<a href=\"https:\/\/casbin.org\/docs\/en\/function\">\u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430<\/a>.<\/p>\n<p>\u0415\u0449\u0451 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u00a0<em>getAllowedTypes<\/em>\u00a0\u043d\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u043c \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u0430\u0432. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0434\u0435\u0441\u044c \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u0439\u0442\u0438 \u043f\u043e \u043f\u0443\u0442\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f, \u0442.\u0435. \u043f\u043e \u043f.1 \u0438\u0437 \u0440\u0430\u0437\u0434\u0435\u043b\u0430 \u0432\u044b\u0448\u0435. \u0414\u043b\u044f handmade \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430 \u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b \u0444\u043e\u043d\u043e\u043c \u0441\u0445\u043e\u0436\u0438\u0439 \u043f\u043e\u0434\u0445\u043e\u0434, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u0432 \u0445\u043e\u0434\u0435 \u0437\u0430\u043c\u0435\u0440\u043e\u0432.<\/p>\n<p>\u0412 \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0435 Casbin\u00a0\u044f \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043c\u0435\u043d\u044f\u043b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043f\u0443\u0449\u0443 \u043a\u043e\u0434, \u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c CLI:<\/p>\n<pre><code class=\"javascript\">async listObjectsByGroup(group) {   \/\/\u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0432\u0441\u0435 \u0442\u0438\u043f\u044b \u0443 \u0433\u0440\u0443\u043f\u043f\u044b   const allTypes = await this.db.getGroupTypes(group);        const allowedTypes = (await Promise.all(     \/\/\u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0442\u0438\u043f\u0443     allTypes.map(async (type) => {       const allowed = await this.enforcer.enforce(this.userLogin, group, type, \"read\");              \/\/\u0435\u0441\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0442\u0438\u043f\u0443 \u0440\u0430\u0437\u0440\u0435\u0448\u0451\u043d, \u0442\u043e \u0432\u0435\u0440\u043d\u0451\u043c \u0442\u0438\u043f       return allowed &amp;&amp; type;     }))     \/\/\u043f\u043e\u0447\u0438\u0441\u0442\u0438\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u0442 undefined \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0442\u0438\u043f\u043e\u0432 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432     .filter(el => el)       if (allowedTypes.length > 0) {     const objects = await Promise.all(       allowedTypes.map(async (type) => await this.db.listObjectsByType(group, type)     )     return objects;   }   else {     return this.denyMessage;   } }<\/code><\/pre>\n<h2>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h2>\n<p>\u0414\u043b\u044f \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u043e\u0432 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0432 Node.js \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439\u00a0<a href=\"https:\/\/nodejs.org\/api\/perf_hooks.html#performancenow\">perfomance.now<\/a>. \u0424\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043b \u0432\u0440\u0435\u043c\u044f \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430 \u0438 \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430, \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u043b \u0440\u0430\u0437\u043d\u0438\u0446\u0443.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/740\/0d6\/89b\/7400d689b2325ee344fbee167586802c.png\" width=\"801\" height=\"440\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/740\/0d6\/89b\/7400d689b2325ee344fbee167586802c.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043d\u0430 \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440 \u043f\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c:<\/p>\n<ul>\n<li>\n<p><em>list obj group={n} type={m}\u00a0\u2013\u00a0<\/em>\u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442 \u043e\u0434\u043d\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043f\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u0442\u0438\u043f\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u0423\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u0438\u043f\u0430 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0437: \u0433\u0440\u0443\u043f\u043f\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 + \u0442\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p><em>list obj group={n}\u00a0\u2013<\/em>\u00a0\u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0433\u0440\u0443\u043f\u043f\u044b. \u0412 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0447\u0435\u0442\u044b\u0440\u0435 \u0442\u0438\u043f\u0430 \u043d\u0430 \u043e\u0434\u043d\u0443 \u0433\u0440\u0443\u043f\u043f\u0443.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 handmade \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c:<\/p>\n<ul>\n<li>\n<p><em>SQL<\/em>\u00a0\u2013\u00a0\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441 \u0438\u043d\u043b\u0430\u0439\u043d SQL-\u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 \u0432 \u0411\u0414<\/p>\n<\/li>\n<li>\n<p><em>ORM<\/em>\u00a0\u2013\u00a0\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0447\u0435\u0440\u0435\u0437 ORM Sequelize<\/p>\n<\/li>\n<li>\n<p><em>getAllowedTypes (GAT)\u00a0\u2013\u00a0<\/em>\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u00a0<em>list obj group={n}\u00a0<\/em>\u0441\u0440\u0430\u0437\u0443 \u043e\u0442\u0434\u0430\u0441\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432, \u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0438\u043f \u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0435\u0441\u0442\u044c \u0434\u043b\u044f SQL \u0438 ORM. \u0412 \u0440\u0430\u043c\u043a\u0430\u0445 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0436\u0438\u043c\u0430 \u044f \u043d\u0435 \u0431\u0443\u0434\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443\u00a0<em>list obj group={n} type={m},\u00a0<\/em>\u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e\u00a0\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0431\u0443\u0434\u0435\u0442 \u0441\u0445\u043e\u0436 \u0441 SQL\/ORM.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 Casbin:<\/p>\n<ul>\n<li>\n<p><em>casbin<\/em>\u00a0\u2013\u00a0\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430 Casbin \u0441 \u0435\u0433\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0443\u044e \u043f\u0430\u043c\u044f\u0442\u044c<\/p>\n<\/li>\n<li>\n<p><em>casbin (no init enf)<\/em>\u00a0\u2013\u00a0\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440 Casbin \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u042f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043a \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c CLI \u043e\u043f\u0446\u0438\u044e<em>\u00a0Enforce Repeats<\/em>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u0430 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u0432 \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430. \u0412\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c\u0441\u044f\u00a0<strong>\u0441\u0440\u0435\u0434\u043d\u0435\u0435\u00a0<\/strong>(average). \u0415\u0434\u0438\u043d\u0438\u0446\u0430 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u0438\u00a0\u2013\u00a0\u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b (ms).<\/p>\n<p>\u0412\u0437\u044f\u043b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 (<em>User<\/em>) \u0441 \u0440\u0430\u0437\u043d\u044b\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0440\u043e\u043b\u0435\u0439 (<em>User Roles<\/em>), \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0432\u043b\u0438\u044f\u043d\u0438\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0440\u043e\u043b\u0435\u0439 \u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<p>\u0410\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0430: Processor: i5-1135G7 @ 2.40GHz, 2419 Mhz, 4 Core(s), 8 Logical Processor(s)<\/p>\n<h3>POOLS x 1<\/h3>\n<p>1 000 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, 16 \u0440\u043e\u043b\u0435\u0439, 32 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0442\u0438\u043f\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439. \u041e\u0431\u044a\u0451\u043c \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0418\u043c\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0421\u0442\u0440\u043e\u043a<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td rowspan=\"4\">\n<p align=\"left\">handmade<\/p>\n<\/td>\n<td>\n<p align=\"left\">Auth<\/p>\n<\/td>\n<td>\n<p align=\"left\">1 000<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Roles<\/p>\n<\/td>\n<td>\n<p align=\"left\">16<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">UserRoles<\/p>\n<\/td>\n<td>\n<p align=\"left\">1 720<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Permissions<\/p>\n<\/td>\n<td>\n<p align=\"left\">352<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">casbin<\/p>\n<\/td>\n<td>\n<p align=\"left\">casbin_rule<\/p>\n<\/td>\n<td>\n<p align=\"left\">2 072<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/671\/da6\/f85\/671da6f85b5afdacf6aa28aaa7c07e37.png\" width=\"1403\" height=\"549\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/671\/da6\/f85\/671da6f85b5afdacf6aa28aaa7c07e37.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041a\u0430\u043a\u0438\u0435 \u0432\u044b\u0432\u043e\u0434\u044b \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0430:<\/p>\n<ul>\n<li>\n<p>\u0438\u043d\u043b\u0430\u0439\u043d SQL-\u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e \u0431\u044b\u0441\u0442\u0440\u043e. \u041d\u043e \u043f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u0432\u0430\u0436\u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043b\u0443\u0436\u0431 \u0438 \u0441\u0435\u0442\u0438 \u043c\u0435\u0436\u0434\u0443 \u0445\u043e\u0441\u0442\u043e\u043c \u0438 \u0421\u0423\u0411\u0414. \u0423 \u0432\u0441\u0435\u0445 \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0434\u0438\u0432\u0438\u0434\u0443\u0430\u043b\u044c\u043d\u0430\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0447\u0435\u0440\u0435\u0437 ORM \u043d\u0430 \u0445\u043e\u043b\u043e\u0434\u043d\u043e\u043c \u0441\u0442\u0430\u0440\u0442\u0435 \u0434\u0430\u044e\u0442 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443. \u041f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043c\u0435\u043d\u044c\u0448\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u041f\u0440\u0438\u043c\u0435\u0440 \u0442\u0440\u0451\u0445 \u0440\u0443\u0447\u043d\u044b\u0445 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u044b <em>list obj group=1 type=1 rep=1<\/em> \u0434\u043b\u044f <em>handmade ORM<\/em> \u0441 \u043f\u0435\u0440\u0435\u0440\u044b\u0432\u043e\u043c ~1 \u0441\u0435\u043a:<\/p>\n<ol>\n<li>\n<p>enforce = 156 ms<\/p>\n<\/li>\n<li>\n<p>enforce = 4 ms<\/p>\n<\/li>\n<li>\n<p>enforce = 5 ms<\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>\n<p>ORM \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u043b\u0438\u0437\u043a\u043e \u043a \u0443\u0440\u043e\u0432\u043d\u044e \u0438\u043d\u043b\u0430\u0439\u043d \u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u041e\u0442\u043b\u0438\u0447\u0430\u0435\u0442 \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u0445\u043e\u043b\u043e\u0434\u043d\u044b\u0439 \u0441\u0442\u0430\u0440\u0442.<\/p>\n<\/li>\n<li>\n<p>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <em>getAllowedTypes<\/em> \u0434\u0430\u043b\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u0440\u0438\u0440\u043e\u0441\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432 \u0438\u043d\u043b\u0430\u0439\u043d SQL \u043f\u0440\u0438 \u0447\u0430\u0441\u0442\u043e\u0439 \u0441\u0440\u0430\u0431\u043e\u0442\u043a\u0435, \u043d\u043e \u043f\u0440\u0438 \u0445\u043e\u043b\u043e\u0434\u043d\u043e\u043c \u0441\u0442\u0430\u0440\u0442\u0435 \u0434\u043b\u044f ORM \u043f\u043e\u043a\u0430\u0437\u0430\u043b \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u0415\u0441\u043b\u0438 \u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440, \u0442\u043e \u043b\u0443\u0447\u0448\u0435 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0438, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0440\u0443\u0436\u0443 \u0431\u044b\u043b\u0430 \u0432\u0438\u0434\u043d\u0430 \u043e\u0434\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <em>enforce<\/em>.<\/p>\n<\/li>\n<li>\n<p>\u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u043e\u043b\u0435\u0439 \u043d\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435 \u043d\u0435 \u0432\u043b\u0438\u044f\u044e\u0442 \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b handmade \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430. \u041d\u043e \u0443 \u0421asbin \u0441\u043b\u043e\u0436\u0438\u043b\u043e\u0441\u044c \u0432\u043f\u0435\u0447\u0430\u0442\u043b\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0432\u043b\u0438\u044f\u0435\u0442.<\/p>\n<\/li>\n<li>\n<p><em>casbin (no init enf) <\/em>\u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043d\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u043b, \u0447\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b CLI \u043d\u0435 \u0441\u0442\u043e\u0438\u0442, \u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0431<strong>\u043e<\/strong>\u043b\u044c\u0448\u0443\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0432\u044b\u0432\u043e\u0434\u043e\u0432 \u0432\u044b\u0448\u0435, \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0445 \u0442\u0435\u0441\u0442\u043e\u0432:<\/p>\n<ul>\n<li>\n<p>\u0443\u0431\u0440\u0430\u043b user750 \u0441 \u0434\u0432\u0443\u043c\u044f \u0440\u043e\u043b\u044f\u043c\u0438, \u043e\u0441\u0442\u0430\u0432\u0438\u043b user930 \u0441 \u0447\u0435\u0442\u044b\u0440\u044c\u043c\u044f<\/p>\n<\/li>\n<li>\n<p>\u0443\u0431\u0440\u0430\u043b<em> handmade (GAT). <\/em>\u0412 \u0446\u0435\u043b\u043e\u043c \u044f \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u0437\u0430 \u0441\u0447\u0451\u0442 \u0442\u0430\u043a\u0438\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0432\u043d\u0443\u0442\u0440\u0438 \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430. \u041d\u043e \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 ORM \u043d\u0443\u0436\u043d\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0442\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u0435\u0435.<\/p>\n<\/li>\n<li>\n<p>\u0443\u0431\u0440\u0430\u043b <em>casbin (no init enf).\u00a0<\/em>\u0412\u043d\u0435 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u043b \u0441 \u043d\u0438\u043c \u0442\u0435\u0441\u0442\u044b. \u0412\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u043b\u0430\u0441\u044c \u0441 \u043e\u0431\u044a\u0451\u043c\u043e\u043c \u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0430 10 \u043f\u0443\u043b\u0430\u0445 <em>list obj group=1 type=1 rep=1 <\/em>\u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u043b 0,6 \u0441\u0435\u043a, \u0430 \u043d\u0430 100 \u043f\u0443\u043b\u0430\u0445 4,426 \u0441\u0435\u043a.<\/p>\n<\/li>\n<\/ul>\n<h3>POOLS x 10<\/h3>\n<p>10 000 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, 160 \u0440\u043e\u043b\u0435\u0439, 320 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0442\u0438\u043f\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439. \u041e\u0431\u044a\u0451\u043c \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0418\u043c\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0421\u0442\u0440\u043e\u043a<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td rowspan=\"4\">\n<p align=\"left\">handmade<\/p>\n<\/td>\n<td>\n<p align=\"left\">Auth<\/p>\n<\/td>\n<td>\n<p align=\"left\">10 000<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Roles<\/p>\n<\/td>\n<td>\n<p align=\"left\">160<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">UserRoles<\/p>\n<\/td>\n<td>\n<p align=\"left\">17 200<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Permissions<\/p>\n<\/td>\n<td>\n<p align=\"left\">3 520<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">casbin<\/p>\n<\/td>\n<td>\n<p align=\"left\">casbin_rule<\/p>\n<\/td>\n<td>\n<p align=\"left\">20 720<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0420\u0430\u043d\u0435\u0435 \u0431\u044b\u043b\u0438 \u0441\u043e\u043c\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0441\u0447\u0451\u0442 \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u043f\u043e user930 \u0443 casbin. \u0417\u0430\u043c\u0435\u043d\u0438\u043b \u0435\u0433\u043e \u043d\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f user9910:  <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1a7\/04d\/c6e\/1a704dc6eb7fa8809dc6b0953005aa35.png\" width=\"961\" height=\"352\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1a7\/04d\/c6e\/1a704dc6eb7fa8809dc6b0953005aa35.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412\u044b\u0432\u043e\u0434\u044b:<\/p>\n<ul>\n<li>\n<p>\u0443 ORM \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043e\u0441\u0442\u0430\u0432\u0438\u043b \u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u0438 \u0447\u0430\u0441\u0442\u043e\u0439 \u0441\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0445\u043e\u043b\u043e\u0434\u043d\u044b\u0439 \u0441\u0442\u0430\u0440\u0442 \u0434\u0430\u0436\u0435 \u043f\u0440\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u0443\u0445\u043e\u0434\u0438\u0442. \u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0439\u0434\u0451\u0442 5-10 \u0441\u0435\u043a, \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 150ms \u043d\u0430 \u0445\u043e\u043b\u043e\u0434\u043d\u043e\u043c \u0438 3ms \u043f\u0440\u0438 \u0447\u0430\u0441\u0442\u043e\u043c \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438.<\/p>\n<\/li>\n<li>\n<p>\u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430 Casbin \u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f: \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0438\u0441\u0435\u0439, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u043e\u043b\u0435\u0439 \u043d\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 \u043f\u043e\u043b\u0438\u0442\u0438\u043a Casbin. \u0422\u0430\u043a\u0438\u0435 \u0432\u044b\u0432\u043e\u0434\u044b \u0441\u0434\u0435\u043b\u0430\u043b \u0438\u0437 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0440\u043e\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0446\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e\u043b\u0438\u0442\u0438\u043a:<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a8f\/345\/273\/a8f34527341b3dd3d4c413b8b59c8625.png\" width=\"632\" height=\"200\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a8f\/345\/273\/a8f34527341b3dd3d4c413b8b59c8625.png\"\/><figcaption><\/figcaption><\/figure>\n<h3>POOLS x 100<\/h3>\n<p>100 000 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, 1 600 \u0440\u043e\u043b\u0435\u0439, 3 200 \u0442\u0438\u043f\u043e\u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439. \u041e\u0431\u044a\u0451\u043c \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0418\u043c\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0421\u0442\u0440\u043e\u043a<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td rowspan=\"4\">\n<p align=\"left\">handmade<\/p>\n<\/td>\n<td>\n<p align=\"left\">Auth<\/p>\n<\/td>\n<td>\n<p align=\"left\">100 000<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Roles<\/p>\n<\/td>\n<td>\n<p align=\"left\">1 600<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">UserRoles<\/p>\n<\/td>\n<td>\n<p align=\"left\">172 000<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Permissions<\/p>\n<\/td>\n<td>\n<p align=\"left\">35 200<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">casbin<\/p>\n<\/td>\n<td>\n<p align=\"left\">casbin_rule<\/p>\n<\/td>\n<td>\n<p align=\"left\">207 200<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p> \u041e\u0441\u0442\u0430\u0432\u0438\u043b \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u043a\u043e\u043d\u0446\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e\u043b\u0438\u0442\u0438\u043a:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/49c\/d98\/55b\/49cd9855b7a42a6c2278fe44ead16617.png\" width=\"979\" height=\"198\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/49c\/d98\/55b\/49cd9855b7a42a6c2278fe44ead16617.png\"\/><figcaption><\/figcaption><\/figure>\n<h2>\u0412\u044b\u0432\u043e\u0434\u044b<\/h2>\n<p>Casbin \u00ab\u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438\u00bb \u0433\u043e\u0442\u043e\u0432 \u043f\u043e\u043a\u0440\u044b\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u0430: RBAC, ABAC, ALC, \u0434\u0440. \u0412 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043c\u043e\u0436\u043d\u043e \u0438\u0445 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u044b \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438. \u0417\u0430 \u0441\u0447\u0451\u0442 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439 \u043a \u0441\u0438\u0441\u0442\u0435\u043c\u0435. \u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430 \u043d\u0430 Node.js \u043f\u0440\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0440\u0435\u0441\u0443\u0440\u0441\u0443 \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0430 ~150ms \u043d\u0430 200 000 \u0437\u0430\u043f\u0438\u0441\u044f\u0445 \u0442\u0430\u0431\u043b\u0438\u0446\u044b Casbin. \u0427\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u044b\u043c \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041d\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u044f\u0437\u044b\u043a\u0430\u0445 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0432\u044b\u0448\u0435.<\/p>\n<p>\u0412 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c Casbin \u0441 handmade \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u0432 \u043c\u0435\u0441\u0442\u0430\u0445, \u0433\u0434\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0431<strong>\u043e<\/strong>\u043b\u044c\u0448\u0430\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u0431\u0443\u0434\u0443\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0442 \u043a\u043e\u043d\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0445. \u0410 \u0442\u0430\u0431\u043b\u0438\u0446\u0430 Casbin \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0443\u0436\u0438\u0442\u044c, \u043a\u0430\u043a \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f. \u0415\u0441\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0443 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u0445 \u0431\u0443\u0434\u0443\u0442 \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f, \u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440 Casbin. \u0423\u0436\u0435 \u0447\u0435\u0440\u0435\u0437 \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u043f\u0430\u0434\u0430\u0442\u044c \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 Casbin. \u041f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0430 \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0443\u0447\u0430\u0441\u0442\u043a\u0430\u0445 \u0438 \u0441\u043a\u043e\u043d\u0446\u0435\u043d\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445.<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430, \u0445\u0440\u0430\u043d\u044f url \u0432 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430\u0445: <em>user1, \/group1\/* , read<\/em>. \u0415\u0441\u043b\u0438 <em>user1<\/em> \u0437\u0430\u0445\u043e\u0447\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435 <em>\/group1\/type4<\/em>, \u0442\u043e \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440 Casbin \u0432\u0435\u0440\u043d\u0451\u0442 <em>true<\/em>. \u0417\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0431\u0443\u0434\u0435\u0442 \u043c\u0435\u043d\u044c\u0448\u0435, \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432\u044b\u0448\u0435.<\/p>\n<p>\u0417\u0430 \u0441\u0447\u0451\u0442 \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b, \u044f \u0441\u043c\u043e\u0433 \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u043d\u044f\u0442\u044c \u043f\u0440\u0438\u0440\u043e\u0434\u0443 Casbin, \u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438. \u0423\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0435\u0433\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438. \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0443\u0436\u0435 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430 \u0434\u043b\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0438 \u0432\u0441\u0451 \u0435\u0449\u0451 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043f\u043e\u043a\u0430 \u0432\u0441\u0451.\u00a0\u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u043e\u0434 \u0440\u0443\u043a\u043e\u0439 \u0441\u043e\u0432\u0435\u0442\u044b \u043f\u043e \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044e\/\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e Casbin, \u0438\u043d\u0444\u043e \u043f\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0442\u0435\u043a\u0430\u0445\/\u043a\u0435\u0439\u0441\u0430\u0445 \u0438\u043b\u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u0441\u044b\u043b\u043a\u0438 \u043f\u043e \u0434\u0430\u043d\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435, \u0442\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0439\u0442\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438. \u041e\u043d\u0438 \u0437\u043d\u0430\u0447\u0438\u043c\u043e \u0441\u043c\u043e\u0433\u0443\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043e\u0431\u0449\u0438\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442\u043e\u0432, \u043a\u0442\u043e \u0438\u0449\u0435\u0442 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u0432 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<h3>\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b<\/h3>\n<ul>\n<li>\n<p><a href=\"https:\/\/github.com\/Qxor\/casbin-cli-prototype\">\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c CLI \u0438\u0437 \u0441\u0442\u0430\u0442\u044c\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/profsandhu.com\/journals\/tissec\/ANSI+INCITS+359-2004.pdf\">ANSI INCITS 359-2004 (\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 RBAC)<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/arxiv.org\/pdf\/1903.09756.pdf\">PML: An Interpreter-Based Access Control Policy Language for Web Services<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/post\/540454\/\">\u0413\u0438\u0431\u043a\u0430\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Casbin \u0438 PERM. \u041f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/casbin.org\/docs\/en\/management-api\">API Casbin<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/sequelize.org\/\">Sequelize<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/bimeister\/blog\/700144\/\"> https:\/\/habr.com\/ru\/company\/bimeister\/blog\/700144\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442!<\/p>\n<p>\u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0410\u043d\u0434\u0440\u0435\u0439 \u0422\u0430\u0431\u043e\u043b\u0438\u043d, \u044f \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a \u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Bimeister.<\/p>\n<p><a href=\"https:\/\/casbin.org\/\">Casbin<\/a>\u00a0\u2013\u00a0\u043e\u0434\u043d\u0430 \u0438\u0437 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043b Casbin, \u043f\u043e\u043f\u0443\u0442\u043d\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b \u0441\u0432\u043e\u0451 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0438\u00a0\u043f\u043e\u043a\u0430\u0436\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u0431\u043e\u0438\u0445. \u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0430\u0441\u044c \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c\u00a0\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0421\u0423\u0411\u0414 \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u043e\u0431\u044a\u0451\u043c\u0430\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0440\u043e\u043b\u0435\u0432\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 (RBAC).\u00a0\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b: Node.js + PostgreSQL.<\/p>\n<h2>\u041f\u0435\u0440\u0435\u0434 \u0441\u0442\u0430\u0440\u0442\u043e\u043c<\/h2>\n<p>\u0414\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0443\u0436\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u0445\u043e\u0442\u044f \u0431\u044b \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 RBAC \u0438 PERM.<\/p>\n<p>RBAC (<em>Role-Based Access Control<\/em>)\u00a0\u2013\u00a0\u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043d\u0430\u0434 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0440\u043e\u043b\u0438 \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0415\u0441\u0442\u044c \u0435\u0449\u0451 ABAC\u00a0\u2013\u00a0\u043c\u043e\u0434\u0435\u043b\u044c, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0430\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b. \u0418 \u0434\u0440\u0443\u0433\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u043a\u0430\u0441\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u043c. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435:\u00a0<a href=\"https:\/\/habr.com\/ru\/company\/custis\/blog\/248649\/\">\u041f\u043e\u0434\u0445\u043e\u0434\u044b \u043a \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044e \u0434\u043e\u0441\u0442\u0443\u043f\u0430: RBAC vs. ABAC<\/a>.<\/p>\n<p>PERM\u00a0(<em>Policy, Effect, Request, Matchers<\/em>) \u2013\u00a0\u043c\u0435\u0442\u0430\u043c\u043e\u0434\u0435\u043b\u044c \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0446\u0435\u043b\u0435\u0432\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430. \u0421 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c: RBAC, ABAC, ACL \u0438 \u0434\u0440. \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 (<em>*.conf<\/em>), \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u043c \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b Casbin. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/post\/539778\/\">RBAC? ABAC?.. PERM! \u041d\u043e\u0432\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u0432\u0435\u0431-\u0441\u043b\u0443\u0436\u0431\u0430\u0445 \u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445<\/a><\/p>\n<\/li>\n<li>\n<p>Casbin:\u00a0<a href=\"https:\/\/casbin.org\/docs\/en\/how-it-works\">How it Works<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/casbin.org\/en\/editor\">\u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440<\/a>\u00a0Casbin \u0434\u043b\u044f \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f PERM<\/p>\n<\/li>\n<\/ul>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/h2>\n<h3>\u0422\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445<\/h3>\n<p>\u042f \u0440\u0435\u0448\u0438\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u00a0\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435:<\/p>\n<ul>\n<li>\n<p>\u041e\u0431\u044a\u0435\u043a\u0442\u044b,\u00a0\u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0434\u043e\u0441\u0442\u0443\u043f<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0434 \u043d\u0438\u043c\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439<\/p>\n<\/li>\n<li>\n<p>\u0420\u043e\u043b\u0438 \u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0432 \u043d\u0438\u0445 \u0432 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0440\u043e\u043b\u0435\u0439 \u043f\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u0431\u044a\u0435\u043a\u0442 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u044c\u0441\u044f\u00a0\u043a \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435 (<em>Group<\/em>) \u0438 \u0442\u0438\u043f\u0443 (<em>Type<\/em>). \u041f\u043e\u0434 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u0432\u043e\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0432\u0438\u0434\u0430: Group1Type1.<br \/>\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043b \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 CRUD (<em>Create Read Update Delete<\/em>) \u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b \u043f\u043e \u043d\u0438\u043c \u0440\u043e\u043b\u0438 \u0441 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438.<br \/>\u0418\u0442\u043e\u0433\u043e, \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043d\u0430\u0431\u043e\u0440\u0435 (<em>Group Set<\/em>) \u0431\u0443\u0434\u0435\u0442\u00a02 \u0433\u0440\u0443\u043f\u043f\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432,\u00a0\u043f\u043e 4 \u0442\u0438\u043f\u0430 \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435,\u00a0\u043f\u043e 4 \u0440\u043e\u043b\u0438 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0438\u043f:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043b \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043e\u0447\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0451\u043c\u0430 \u0434\u043b\u044f \u0440\u043e\u043b\u0435\u0432\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b \u0433\u0440\u0443\u043f\u043f\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 (<em>User Gr<\/em>), \u043d\u0430\u0437\u043d\u0430\u0447\u0438\u043b \u0438\u043c \u0440\u043e\u043b\u0438. \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u043e\u043b\u0435\u0439 \u043d\u0430 \u0433\u0440\u0443\u043f\u043f\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f, \u043e\u0434\u0438\u043d \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0433\u0440\u0443\u043f\u043f\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043b\u0430\u0434\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0440\u043e\u043b\u044f\u043c\u0438.<\/p>\n<p>\u0418\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430\u0437\u0432\u0430\u043b \u043f\u0443\u043b (<em>Pool<\/em>), \u043e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442:<\/p>\n<ul>\n<li>\n<p>32 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0442\u0438\u043f\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 = 32 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u043f\u043e 10 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432 \u043a\u0430\u0436\u0434\u043e\u0439. \u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u043e\u043b\u0435\u0432\u043e\u0439 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>16 \u0440\u043e\u043b\u0435\u0439, \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0445 \u043c\u0435\u0436\u0434\u0443 1000 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0435 \u043f\u0443\u043b\u0430 \u0437\u0430\u043b\u043e\u0436\u0438\u043b \u043c\u043d\u043e\u0436\u0438\u0442\u0435\u043b\u044c. \u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u043e\u0431\u044a\u0451\u043c\u0430\u0445: 1 \u043f\u0443\u043b, 2 \u043f\u0443\u043b\u0430 \u0438\u043b\u0438 10.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f RBAC \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430.<\/p>\n<h3>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439<\/h3>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 RBAC \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0434\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438\u00a0\u2013\u00a0\u0447\u0442\u0435\u043d\u0438\u0435. \u041c\u043d\u0435 \u0432\u0430\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f: \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043d\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0438\u043b\u0438 \u043d\u0435\u0442.<\/p>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u043e\u0432 \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0443\u044e\u00a0<a href=\"https:\/\/github.com\/Qxor\/casbin-cli-prototype\">\u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u0443\u044e \u0443\u0442\u0438\u043b\u0438\u0442\u0443 (CLI)<\/a>,\u00a0\u0442\u0430\u043a \u0431\u044b\u043b\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0431\u0443\u0434\u0443\u0442 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c \u0441\u0442\u0438\u043b\u0435:<\/p>\n<ul>\n<li>\n<p>\u0445\u043e\u0447\u0443 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0438 \u0442\u0438\u043f\u0430:\u00a0<em>list obj group=1 type=1<\/em><\/p>\n<\/li>\n<li>\n<p>\u0445\u043e\u0447\u0443 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043c\u043d\u0435 \u0442\u0438\u043f\u043e\u0432 \u0438\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b: <em>list obj group=1<\/em><\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430. \u0412 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b, \u043a\u0430\u043a \u0431\u044b\u0441\u0442\u0440\u043e \u0440\u043e\u043b\u0435\u0432\u0430\u044f:<\/p>\n<ul>\n<li>\n<p><em>group, type<\/em>\u00a0\u2013\u00a0\u043f\u0440\u0438\u043c\u0435\u0442 \u0440\u0435\u0448\u0435\u043d\u0438\u0435: \u0438\u043c\u0435\u044e \u044f \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435 \u0438 \u0442\u0438\u043f\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432<\/p>\n<\/li>\n<li>\n<p><em>group<\/em>\u00a0\u2013\u00a0\u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0438\u043f \u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b, \u0432 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0443 \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u044b CLI \u043e\u0442\u0440\u0430\u0436\u0430\u044e\u0442 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0435 \u043a\u0435\u0439\u0441\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:<\/p>\n<ul>\n<li>\n<p>\u0437\u0430\u0448\u0451\u043b \u0432 \u0440\u0430\u0437\u0434\u0435\u043b \u0438 \u0432\u0438\u0436\u0443\/\u043d\u0435 \u0432\u0438\u0436\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u044b<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u0448\u0451\u043b \u0432 \u0440\u0430\u0437\u0434\u0435\u043b \u0438 \u0432\u0438\u0436\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432<\/p>\n<\/li>\n<\/ul>\n<h3>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 Casbin<\/h3>\n<p>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b \u0441\u0430\u043c\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 Casbin \u043f\u043e\u00a0<a href=\"https:\/\/casbin.org\/docs\/en\/get-started\">\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438<\/a>\u00a0\u043e\u0442 \u0430\u0432\u0442\u043e\u0440\u043e\u0432 \u0434\u043b\u044f Node.js.\u00a0<\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0421\u0423\u0411\u0414\u00a0Casbin \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u00a0<a href=\"https:\/\/casbin.org\/docs\/en\/adapters\">\u0430\u0434\u0430\u043f\u0442\u0435\u0440\u044b<\/a>\u00a0\u043a\u0430\u043a\u00a0middleware. \u0412\u044b\u0431\u043e\u0440 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u044f\u0437\u044b\u043a\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0441\u0430\u043c\u043e\u0433\u043e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u043e\u0434 \u043c\u043e\u0439 \u0441\u0442\u0435\u043a \u0438 \u0437\u0430\u0434\u0430\u0447\u0443 \u0432\u0437\u044f\u043b\u00a0<a href=\"https:\/\/github.com\/node-casbin\/sequelize-adapter\">Sequelize Adapter<\/a>. \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043c\u043d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u00a0<a href=\"https:\/\/node-postgres.com\/\">pg<\/a>\u00a0\u0434\u043b\u044f PostgreSQL\u00a0\u2013\u00a0\u0432\u044b\u0434\u0430\u0432\u0430\u043b\u043e \u043e\u0448\u0438\u0431\u043a\u0443 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435. \u0414\u0440\u0430\u0439\u0432\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u0438\u043c Sequelize Adapter.<\/p>\n<p>\u0423 Casbin \u0435\u0441\u0442\u044c\u00a0<a href=\"https:\/\/casbin.org\/docs\/en\/policy-storage#database-storage-format\">\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u0442\u0430\u0431\u043b\u0438\u0446\u0435<\/a>, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u044b \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441\u0430\u043c\u0438 \u043f\u043e-\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e. \u041d\u043e \u0441 \u043c\u043e\u0438\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u044f\u0432\u043d\u043e, \u0441\u0442\u0440\u043e\u0433\u043e \u0441 \u0438\u043c\u0435\u043d\u0435\u043c\u00a0\u00abcasbin_rule\u00bb\u00a0\u0438 \u043f\u043e\u043b\u044f\u043c\u0438 \u043d\u0438\u0436\u0435. \u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u043a\u043b\u044e\u0447. Casbin \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430\u043c\u0438, \u043d\u043e\u00a0\u043d\u0435 \u0441 id\u00a0\u0437\u0430\u043f\u0438\u0441\u0435\u0439. \u0421\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430 \u0438\u043b\u0438 \u0440\u0443\u043a\u0430\u043c\u0438. \u042f \u0441\u043e\u0437\u0434\u0430\u043b \u0440\u0443\u043a\u0430\u043c\u0438 \u0432 \u0421\u0423\u0411\u0414.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\"><strong>\u041f\u043e\u043b\u0435<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\">id<\/p>\n<\/td>\n<td>\n<p align=\"left\">serial,\u00a0Primary Key  <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\">ptype<\/p>\n<\/td>\n<td>\n<p align=\"left\">varchar 255, null  <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\">v0<\/p>\n<\/td>\n<td>\n<p align=\"left\">varchar 255, null  <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\">v1<\/p>\n<\/td>\n<td>\n<p align=\"left\">varchar 255, null  <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\">v2<\/p>\n<\/td>\n<td>\n<p align=\"left\">varchar 255, null  <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\">v3<\/p>\n<\/td>\n<td>\n<p align=\"left\">varchar 255, null  <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\">v4<\/p>\n<\/td>\n<td>\n<p align=\"left\">varchar 255, null  <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"118\" width=\"118\">\n<p align=\"left\">v5<\/p>\n<\/td>\n<td>\n<p align=\"left\">varchar 255, null  <\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0418\u043d\u0444\u043e \u043f\u043e \u043f\u043e\u043b\u044f\u043c:<\/p>\n<ul>\n<li>\n<p><em>id<\/em>\u00a0\u2013\u00a0\u0438\u0434 \u0437\u0430\u043f\u0438\u0441\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b<\/p>\n<\/li>\n<li>\n<p><em>ptype<\/em>\u00a0\u2013\u00a0\u0442\u0438\u043f \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 Casbin<\/p>\n<\/li>\n<li>\n<p><em>v0 &#8212; v5<\/em>\u00a0\u2013\u00a0\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 [policy_definition] \u0444\u0430\u0439\u043b\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Casbin<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u043b \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u044e\u00a0<a href=\"https:\/\/casbin.org\/docs\/en\/adapters#how-to-write-an-adapter\">\u043f\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438<\/a>.<\/p>\n<p>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b \u0444\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Casbin (<em>.conf<\/em>):<\/p>\n<pre><code>[request_definition] r = sub, objGroup, objType, act   [policy_definition] p = sub, objGroup, objType, act   [role_definition] g = _, _   [policy_effect] e = some(where (p.eft == allow))   [matchers] m = g(r.sub, p.sub) &amp;&amp; r.objGroup == p.objGroup &amp;&amp; r.objType == p.objType &amp;&amp; r.act == p.act<\/code><\/pre>\n<p>\u0423 \u043c\u0435\u043d\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043c\u0430\u043f\u043f\u0438\u043d\u0433 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0444\u0430\u0439\u043b\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 Casbin \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435\u0439\u00a0<em>casbin_rule<\/em>:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0412\u00a0\u00abcasbin_rule\u00bb\u00a0\u0432\u043d\u0451\u0441 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u044b Casbin \u0441 \u0421\u0423\u0411\u0414. \u0412\u044b\u0432\u0435\u043b \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u00a0\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u043f\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0443, \u0443\u043a\u0430\u0437\u0430\u0432: \u0440\u043e\u043b\u044c, \u0433\u0440\u0443\u043f\u043f\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u0438\u0445 \u0442\u0438\u043f.<\/p>\n<pre><code class=\"javascript\">import { newEnforcer } from \"casbin\"; import { SequelizeAdapter } from \"casbin-sequelize-adapter\";   const app = async () => {   \/\/\u0433\u043e\u0442\u043e\u0432\u0438\u043c \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0434\u043b\u044f \u0421\u0423\u0411\u0414   const adapter = await SequelizeAdapter.newAdapter({     username: \"postgres\",     password: \"password\",     database: \"casbin\",     dialect: \"postgresql\",     logging: false,  \/\/\u0432\u044b\u043a\u043b\u044e\u0447\u0438\u043b\u0438 \u043b\u043e\u0433\u0438 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c, \u043c\u0435\u0448\u0430\u044e\u0442   });         \/\/\u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043e\u0431\u044a\u0435\u043a\u0442 casbin, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430\u043c\u0438,   \/\/\u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0438 \u0430\u0434\u0430\u043f\u0442\u0435\u0440   const e = await newEnforcer(\".\/rbac_model.conf\", adapter);     \/\/\u0447\u0435\u0440\u0435\u0437 API \u043e\u0431\u044a\u0435\u043a\u0442\u0430 casbin \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u043f\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0443, \u043f\u0435\u0440\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 - \u043d\u043e\u043c\u0435\u0440 \u043f\u043e\u043b\u044f v*   \/\/v0 == \"role1\", v1 == \"group1\", v2 == \"type1\"   const rules = await e.getFilteredPolicy(0, \"role1\", \"group1\", \"type1\");     \/\/\u0437\u0430\u043a\u0440\u043e\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0421\u0423\u0411\u0414   await adapter.close();   console.log(rules); };   app() \/\/\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f: [ [ 'role1', 'group1', 'type1', 'read' ] ]<\/code><\/pre>\n<p>\u0421\u0443\u043f\u0435\u0440, \u0434\u043e\u0440\u043e\u0433\u0443 \u043a \u0421\u0423\u0411\u0414\u00a0\u0447\u0435\u0440\u0435\u0437 Casbin \u043f\u0440\u043e\u043b\u043e\u0436\u0438\u043b. \u0414\u0430\u043b\u044c\u0448\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435.<\/p>\n<h3>\u0425\u0440\u0430\u043d\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0420\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u0431\u0443\u0434\u0443 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0432\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0440\u043e\u043b\u0435\u0432\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438: Casbin \u0438 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u0443\u044e (<em>handmade<\/em>) \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432 \u0411\u0414:<\/p>\n<ul>\n<li>\n<p>Users &#8212; \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438<\/p>\n<\/li>\n<li>\n<p>Auth &#8212; \u043b\u043e\u0433\u0438\u043d\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439<\/p>\n<\/li>\n<li>\n<p>Roles &#8212; \u0440\u043e\u043b\u0438<\/p>\n<\/li>\n<li>\n<p>Permissions &#8212; \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430. \u041e\u0434\u043d\u0430 \u0440\u043e\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 (<em>permissions<\/em>) \u0432 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u043b\u0438 \u043c\u043d\u043e\u0433\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>UserRoles &#8212; \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u043d\u0438\u0445 \u0440\u043e\u043b\u0438<\/p>\n<\/li>\n<li>\n<p>casbin_rule &#8212; \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0434\u043b\u044f Casbin, \u043e\u0431\u0441\u0443\u0434\u0438\u043b\u0438 \u0432\u044b\u0448\u0435 \u0438 \u0443\u0436\u0435 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438<\/p>\n<\/li>\n<li>\n<p>Objects* &#8212; \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0434\u043b\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u0443\u043b\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043f\u0430\u0440\u044b \u0442\u0430\u0431\u043b\u0438\u0446. \u0412 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u043e \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0435 \u0411\u0414, \u0434\u0443\u043c\u0430\u044e, \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e.\u00a0<\/p>\n<p><em>\u0442\u0430\u0431\u043b.\u00a0\u00abcasbin_rule\u00bb<\/em><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>id<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>ptype<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>v0<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>v1<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>v2<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>v3<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>v4<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>v5<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">1<\/p>\n<\/td>\n<td>\n<p align=\"left\">p<\/p>\n<\/td>\n<td>\n<p align=\"left\">role1<\/p>\n<\/td>\n<td>\n<p align=\"left\">group1<\/p>\n<\/td>\n<td>\n<p align=\"left\">type1<\/p>\n<\/td>\n<td>\n<p align=\"left\">read<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">2<\/p>\n<\/td>\n<td>\n<p align=\"left\">p<\/p>\n<\/td>\n<td>\n<p align=\"left\">role2<\/p>\n<\/td>\n<td>\n<p align=\"left\">group2<\/p>\n<\/td>\n<td>\n<p align=\"left\">type2<\/p>\n<\/td>\n<td>\n<p align=\"left\">read<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">3<\/p>\n<\/td>\n<td>\n<p align=\"left\">p<\/p>\n<\/td>\n<td>\n<p align=\"left\">role2<\/p>\n<\/td>\n<td>\n<p align=\"left\">group2<\/p>\n<\/td>\n<td>\n<p align=\"left\">type2<\/p>\n<\/td>\n<td>\n<p align=\"left\">create<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><em>\u0442\u0430\u0431\u043b. \u00abPermissions\u00bb<\/em>  <\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>Id<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>RoleId<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>ObjectGroup<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>ObjectType<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>Permission<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">1<\/p>\n<\/td>\n<td>\n<p align=\"left\">1<\/p>\n<\/td>\n<td>\n<p align=\"left\">group1<\/p>\n<\/td>\n<td>\n<p align=\"left\">type1<\/p>\n<\/td>\n<td>\n<p align=\"left\">read<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">2<\/p>\n<\/td>\n<td>\n<p align=\"left\">2<\/p>\n<\/td>\n<td>\n<p align=\"left\">group2<\/p>\n<\/td>\n<td>\n<p align=\"left\">type2<\/p>\n<\/td>\n<td>\n<p align=\"left\">read<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">3<\/p>\n<\/td>\n<td>\n<p align=\"left\">2<\/p>\n<\/td>\n<td>\n<p align=\"left\">group2<\/p>\n<\/td>\n<td>\n<p align=\"left\">type2<\/p>\n<\/td>\n<td>\n<p align=\"left\">create<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430\u00a0\u0444\u0443\u043d\u043a\u0446\u0438\u0439<\/h2>\n<h3>\u041a\u043e\u043c\u0430\u043d\u0434\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/h3>\n<p>\u041e\u0431\u0449\u0438\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0439 CLI \u043f\u0440\u043e\u0441\u0442 \u0438 \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438: handmade \u0438\u043b\u0438 \u0421asbin. \u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u043c\u0430\u043d\u0434\u044b\u00a0<em>list obj<\/em>\u00a0\u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0418\u0437 \u0441\u0445\u0435\u043c\u044b \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f CLI \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c:<\/p>\n<ul>\n<li>\n<p><strong>\u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440<\/strong>\u00a0\u2013\u00a0\u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0430\u044f \u0434\u043e\u0441\u0442\u0443\u043f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443. \u0412\u0437\u044f\u043b \u0438\u0437 \u0442\u0435\u0440\u043c\u0438\u043d\u043e\u043b\u043e\u0433\u0438\u0438 Casbin \u0434\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0411\u0414<\/p>\n<\/li>\n<\/ul>\n<p>\u0417\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"javascript\">async someCliFunc(user, obj, act) {   \/\/\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438   const allowed = await enforce(user, obj, act);       \/\/\u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043e, \u0442\u043e \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435. \u0415\u0441\u043b\u0438 \u043d\u0435\u0442, \u0442\u043e \u043e\u0442\u043a\u0430\u0437   if (allowed) {     const objects = await this.db.listObjects();     return objects;   } else {     return this.denyMessage;   } }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u0448\u0451\u043b \u043a \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0435\u00a0\u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439\u00a0<em>enforce.<\/em><\/p>\n<h4>Handmade \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440<\/h4>\n<p>\u0414\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u0441\u0445\u0435\u043c\u044b \u0411\u0414 \u043c\u043d\u0435 \u0431\u044b\u043b\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"javascript\">\/\/db - \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 DB \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0421\u0423\u0411\u0414, \/\/\u0432 \u043d\u0451\u043c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u044b \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b const enforce = async (db, user, group, type, act) => {       \/\/\u0437\u0430\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b Permissions \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0443   const permissions = await db.getUserPermissions(user, group, type, act);     \/\/\u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u044c \u043e\u0434\u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c \u0435\u0441\u0442\u044c, \u0442\u043e \u0434\u043e\u0441\u0442\u0443\u043f \u0440\u0430\u0437\u0440\u0435\u0448\u0451\u043d   return permissions.length > 0; }<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0411\u0414 (<em>db<\/em>) \u0432\u044b\u043d\u0435\u0441 \u0437\u0430 \u0440\u0430\u043c\u043a\u0438 \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430, \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u043e \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438. \u041e\u0434\u0438\u043d \u0440\u0430\u0437 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0438 \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f. \u041d\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435\u00a0<em>Permissions<\/em>\u00a0\u0432 \u043c\u043e\u0435\u0439 \u0441\u0445\u0435\u043c\u0435 \u043d\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041d\u043e \u0442.\u043a. \u044f \u0433\u043e\u0442\u043e\u0432\u0438\u043b handmade, \u0442\u043e \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0437\u0430\u043f\u0440\u0435\u0449\u0430\u043b \u043c\u043d\u0435 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435\u00a0<em>db.getUserPermissions<\/em>\u00a0\u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c sql-\u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u0438\u0434\u0430:<\/p>\n<pre><code class=\"sql\">with rolesId as (       select userRoles.\"RoleId\" from public.\"UserRoles\" as userRoles       inner join public.\"Auth\" as auth       on auth.\"UserId\" = userRoles.\"UserId\"       where auth.\"Login\"='${user}'     )                 select * from public.\"Permissions\" as perm inner join rolesId on rolesId.\"RoleId\" = perm.\"RoleId\" where perm.\"ObjectGroup\"='${group}'   and perm.\"ObjectType\"='${type}'   and perm.\"Permission\"='${act}'<\/code><\/pre>\n<p>\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 \u0438\u043d\u043b\u0430\u0439\u043d SQL-\u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f ORM. \u0412 \u043c\u043e\u0451\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0442 \u0436\u0435 Sequelize. \u0414\u043b\u044f \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044f \u0444\u043e\u043d\u043e\u043c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e handmade \u043d\u0430 \u043d\u0451\u043c.  <\/p>\n<h4>Casbin \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440<\/h4>\n<p>\u041d\u0430 \u0441\u0430\u0439\u0442\u0435 Casbin \u0435\u0441\u0442\u044c\u00a0<a href=\"https:\/\/casbin.org\/docs\/en\/get-started\">\u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440\u0430<\/a>.<\/p>\n<p>\u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044f \u043f\u043e\u0448\u0451\u043b\u00a0\u0441\u0445\u043e\u0436\u0438\u043c \u0441 handmade \u043f\u0443\u0442\u0451\u043c\u00a0\u2013\u00a0\u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440.\u00a0\u0424\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0421asbin \u0438 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u043a \u0411\u0414 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0441 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435. \u041c\u043e\u0449\u043d\u043e, \u043a\u0440\u0443\u0442\u043e.<\/p>\n<pre><code class=\"javascript\">const enforce = async (model, adapter, ...args) => {   const e = await casbin.newEnforcer(model, adapter);      \/\/\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 Casbin-\u0438\u043d\u0444\u043e\u0440\u0441\u0435\u0440   const allowed = await e.enforce(...args);     await adapter.close();   return allowed; };<\/code><\/pre>\n<p>\u041d\u043e \u0440\u0430\u0434\u043e\u0441\u0442\u044c \u043c\u043e\u044f \u0431\u044b\u0441\u0442\u0440\u043e \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0430\u0441\u044c, \u043a\u043e\u0433\u0434\u0430 \u044f \u043d\u0430\u0447\u0430\u043b<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-341447","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/341447","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=341447"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/341447\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=341447"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=341447"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=341447"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}