Разработка сайта для Вашего бизнеса. Веб дизайн. Дизайн логотипа, фирменного стиля, рекламная фотография . Комплексный рекламный креатив.

Ralex. We do the work.
На рынке с 1999го года. Средняя ценовая категория. Ориентация на эффективность решений.
Ознакомтесь с нашим портфолио
Узнайте больше о услугах
Свяжитесь с нами:
E-mail: [email protected]
Tel: (044) 587 - 84 - 78
Custom web design & дизайн и разработка сайта "под ключ"
Креативный, эффективный дизайн. Система управления сайтом (СУС).
Custom flexible разработка систем электронной коммерции
Система e-commerce разрабатывается под индивидуальные потребности. Гибкая функциональность.
Search Engine Optimzation & оптимизация под поисковые системы (SEO)
Постоянная оптимизация и мониторинг сайта в поисковых системах. Достигаем результата быстро и эффективно
Custom logo design & дизайн логотипа и фирменного стиля
Многолетний опыт. Огромное портфолио. Уникальное предложение и цена.
профессиональная рекламная фотография
креативно, смело, качественно
Custom logo design & рекламный креатив. дизайн рекламы
Многолетний опыт. Огромное портфолио. Уникальное предложение и цена.

Yii PHP framework: контроль доступу з використанням ролей (RBAC)

Наша взаимовыгодная связь https://banwar.org/

Я думаю, всі, хто хоч трохи працював з фреймворком Yii знають, що він підтримує можливість розмежування прав доступу на основі ролей.

Принцип роботи цієї системи досить простий. Ви створюєте набори правил і користувачів, пов'язуєте їх між собою. Після цього, ви в будь-який момент можете перевірити, чи має користувач право на виконання якоїсь операції чи ні.

Одне з основних переваг використання даної бібліотеки полягає в тому, що вам потрібно написати мінімум коду для перевірки прав доступу. Зазвичай цей код виглядає наступним чином.

if (! Yii :: app () -> user-> checkAccess ( 'createUser')) {throw new CHttpException (403, 'Forbidden'); } // решті код ...

В теорії все просто. Але на практиці, документації і прикладів по цій темі практично немає (сподіваюся, це скоро зміниться).

Основні джерела інформації (російською): Аутентифікація і авторизація і RBAC і опис ролей в файлі . Англійською хороших і докладних прикладів, на жаль, я не знайшов.

Примітка. Дуже раджу прочитати ці статті, перш ніж переходити до мій приклад.

Коли я перший раз вирішив використовувати RBAC, то з'ясувалося, що є безліч нюансів, які доводиться враховувати при роботі з цією бібліотекою. Нічого вкрай складного і недоступного для розуміння, але «копирсався» я досить довго 😉

У цій статті ми розглянемо приклад створення нескладної системи управління користувачами (ідея взята з одного web додатки).

Постановка задачі.

Є три типи користувачів.

Звичайний (user) - може створювати і редагувати свої дані (наприклад, список контактів) і змінювати свої логін / пароль.

Адміністратор (admin) - може створювати нових користувачів, але не може змінювати їх дані. Він може змінити свої власні логін та пароль, але не може змінити роль.

Суперкористувач (root) - може виконувати будь-які операції з користувачами.

Ні admin, ні root не мають доступу до персональних даних користувача (які він створює при роботі з додатком).

Примітка. Щоб скоротити обсяг коду, я урізав набір правил. Але, думаю, ви без особливих зусиль зможете його доповнити. Головне зрозуміти ідею і принцип роботи.

Крок перший. Вибираємо тип сховища для ролей і операцій.

Для цих цілей Yii дозволяє використовувати PHP файл (CPhpAuthManager) або базу даних (CDbAuthManager).

Якщо ви припускаєте, що кількість користувачів буде великим, то краще використовувати БД. Але для знайомства з бібліотекою краще використовувати PHP файл, тому що читати його легше. До того ж перейти від одного типу сховища до іншого зовсім нескладно.

Для того, щоб Yii «дізнався» про вашому виборі, в масив з настройками (config / main.php) потрібно додати наступний елемент.

'Components' => array (... 'authManager' => array ( 'class' => 'CPhpAuthManager',),),

Крок другий. Створимо таблицю в БД для зберігання користувачів.

Ця таблиця буде складатися з шести полів.

u_id - первинний ключ;
u_name - ім'я користувача;
u_email - адреса електронної пошти (використовується як логін);
u_pass - пароль;
u_state - статус (активний, заблокований);
u_role - роль користувача (root, admin, user).

В даному прикладі для нас відіграє роль останнім поле (u_role).

Крок третій. Створюємо операції, ролі і завдання.

Я дуже сподіваюся, що ви прочитали статтю з повного керівництва і знаєте, що представляють собою операції, ролі і завдання і навіщо вони потрібні.

Відразу перейдемо до створення файлу з цими настройками.

Оскільки в якості сховища ми вибрали PHP файл, то можна створити його вручну (цей спосіб докладно розглянуто в статті RBAC і опис ролей в файлі ).

Але, на мій погляд, набагато зручніше використовувати API. Тому створимо невеликий інсталяційний скрипт (контролер SiteController метод actionInstall).

Примітка. Дані будуть збережені у файлі protected / data / auth.php. Файл буде створений автоматично, тому запис в цю папку повинна бути дозволена.

public function actionInstall () {$ auth = Yii :: app () -> authManager; // скидаємо всі існуючі правила $ auth-> clearAll (); // Операції управління користувачами. $ Auth-> createOperation ( 'createUser', 'створення користувача'); $ Auth-> createOperation ( 'viewUsers', 'перегляд списку користувачів'); $ Auth-> createOperation ( 'readUser', 'перегляд даних користувача'); $ Auth-> createOperation ( 'updateUser', 'зміна даних користувача'); $ Auth-> createOperation ( 'deleteUser', 'видалення користувача'); $ Auth-> createOperation ( 'changeRole', 'зміна ролі користувача'); $ BizRule = 'return Yii :: app () -> user-> id == $ params [ "user"] -> u_id;'; $ Task = $ auth-> createTask ( 'updateOwnData', 'зміна своїх даних', $ bizRule); $ Task-> addChild ( 'updateUser'); // створюємо роль для користувача admin і вказуємо, які операції він може виконувати $ role = $ auth-> createRole ( 'admin'); $ Role-> addChild ( 'createUser'); $ Role-> addChild ( 'viewUsers'); $ Role-> addChild ( 'readUser'); $ Role-> addChild ( 'updateOwnData'); // всі користувачі будуть створюватися за замовчуванням з роллю user, // тільки root може змінювати роль іншого користувача // створюємо роль для користувача root $ role = $ auth-> createRole ( 'root'); // успадковуємо операції, визначені для admin'а і додаємо нові $ role-> addChild ( 'admin'); $ Role-> addChild ( 'updateUser'); $ Role-> addChild ( 'deleteUser'); $ Role-> addChild ( 'changeRole'); // створюємо операції для user'а $ bizRule = 'return Yii :: app () -> user-> id == $ params [ "contact"] -> c_user_id;'; $ Auth-> createOperation ( 'createContact', 'створення контакту'); $ Auth-> createOperation ( 'viewContacts', 'перегляд списку контактів'); $ Auth-> createOperation ( 'readContact', 'перегляд контакту', $ bizRule); $ Auth-> createOperation ( 'updateContact', 'редагування контакту', $ bizRule); $ Auth-> createTask ( 'deleteContact', 'видалення контакту', $ bizRule); // створюємо роль user і додаємо операції для неї $ user = $ auth-> createRole ( 'user'); $ User-> addChild ( 'createContact'); $ User-> addChild ( 'viewContacts'); $ User-> addChild ( 'readContact'); $ User-> addChild ( 'updateContact'); $ User-> addChild ( 'deleteContact'); $ User-> addChild ( 'updateOwnData'); // створюємо користувача root (запис в БД в таблиці users) // тут використовуємо DAO, тому що AR автоматично призначить користувачеві роль user $ sql = 'INSERT INTO users (u_name, u_email, u_pass, u_state, u_role)'. ' VALUES ( "root", "[email protected]", " '.md5 (' 11111 ').'", '.Users :: STATE_ACTIVE.', " '.Users :: ROLE_ROOT.'") '; $ Conn = Yii :: app () -> db; $ Conn-> createCommand ($ sql) -> execute (); // пов'язуємо користувача з роллю $ auth-> assign ( 'root', $ conn-> getLastInsertID ()); // зберігаємо ролі і операції $ auth-> save (); $ This-> render ( 'install'); }

Метод вийшов досить об'ємний, але в ньому більшу частину займаю виклики createOperation і addChild, які створюють операції і пов'язують їх з ролями.

Більшість операцій в цьому прикладі відповідають методам контролера (CRUD), але вони можуть бути будь-якими. Наприклад, такими як changeRole, що дозволяють змінювати одне єдине поле записи.

Зверніть увагу. Після створення операцій і ролей доступ обмежений не буде. Ви повинні будете самі перевірити у користувача наявність прав за допомогою методу checkAccess.

На окрему увагу заслуговує використання бізнес правил (bizRule) в операціях.

Бізнес правило являє собою звичайний PHP код, який повинен повертати true або false. Цей код може отримати масив з даними, який буде доступний через змінну $ params.

Розглянемо правило

$ BizRule = 'return Yii :: app () -> user-> id == $ params [ "user"] -> u_id;';

Тут ми перевіряємо, чи відповідають id поточного користувача (який виконав вхід) і id записи в таблиці користувачів, яку він хоче змінити. Таким чином, це правило дозволить користувачеві редагувати тільки свої дані.

В кінці методу ми створюємо користувача root. Справа в тому, що всі користувачі будуть створюватися за участю user і тільки root може змінювати роль. Тому ми створюємо його відразу при інсталяції.

Після створення користувача призначаємо йому роль (метод assign) і зберігаємо зміни
$ Auth-> save ();

Крок четвертий. Створення моделі для роботи з користувачами.

Як завжди, створюємо модель за допомогою генератора (gii) і потім вносимо свої зміни.

Весь код моделі я приводити тут не буду (в кінці статті є посилання на архів з прикладом). Розглянемо лише змінені методи.

public function beforeSave () {parent :: beforeSave (); $ This-> u_pass = md5 ($ this-> u_pass); / * * Якщо користувач не має права змінювати роль, то ми повинні * встановити роль за замовчуванням (user) * / if (! Yii :: app () -> user-> checkAccess ( 'changeRole')) {if ($ this-> isNewRecord) {// ставимо роль по-замовчуванню user $ this-> u_role = Users :: ROLE_USER; }} Return true; }

Перед створенням нової записи ми перевіряємо, чи має поточної користувач право змінювати ролі, якщо немає, то ставимо роль за замовчуванням (user).

Після збереження (або створення) записи, потрібно призначити користувачеві роль. Права користувача ми вже перевірили і роль встановили, тому зараз просто призначаємо користувачеві роль (метод assign).

Попередньо, за допомогою методу revoke видаляємо зв'язок між користувачем і роллю (якщо така існувала). Якщо зв'язок не видалити, то коли root буде змінювати ролі, у нас з'являться користувачі з декількома ролями.

public function afterSave () {parent :: afterSave (); // пов'язуємо нового користувача з роллю $ auth = Yii :: app () -> authManager; // попередньо видаляємо стару зв'язок $ auth-> revoke ($ this-> prevRole, $ this-> u_id); $ Auth-> assign ($ this-> u_role, $ this-> u_id); $ Auth-> save (); return true; }

При видаленні користувача не забуваємо видалити зв'язок між ним і роллю.

public function beforeDelete () {parent :: beforeDelete (); // прибираємо зв'язок віддаленого користувача з роллю $ auth = Yii :: app () -> authManager; $ Auth-> revoke ($ this-> u_role, $ this-> u_id); $ Auth-> save (); return true; }

Як бачите, принцип роботи досить простий. Головне, не забувайте викликати $ auth-> save (); щоб зберегти зміни.

Крок п'ятий. Контролер та подання.

Як і у випадку з моделлю, створюємо контролер і представлення за допомогою генератора (gii).

Методи filters і accessRules можна прибрати, тому що їх ми не використовуємо. В інші методи додаємо перевірку прав користувача.

Знову ж, весь контролер цілком розглядати немає сенсу, він є в архіві з кодами. Як приклад розглянемо метод оновлення даних користувача.

Це найскладніший випадок. У нас є користувач, якому можна змінювати будь-які записи, є користувачі, яким можна змінювати тільки свій запис, але при цьому не можна змінювати свою роль. Тому перевірок буде дві.

У перший раз перевіряємо, чи намагається змінити роль користувач, у якого на це немає прав.

За допомогою другої перевірки переконуємося, що у користувача є права на зміну цього запису.

public function actionUpdate () {$ model = $ this-> loadModel (); // перевіряємо, чи можна користувачу змінювати роль if (isset ($ _ POST [ 'Users'] [ 'u_role']) &&! Yii :: app () -> user-> checkAccess ( 'changeRole')) {throw new CHttpException (403, 'Forbidden'); } // перевіряємо, чи може користувач змінювати даний запис if (! Yii :: app () -> user-> checkAccess ( 'updateUser') &&! Yii :: app () -> user-> checkAccess ( 'updateOwnData', array ( 'user' => $ model))) {throw new CHttpException (403, 'Forbidden'); } If (isset ($ _ POST [ 'Users'])) {$ model-> prevRole = $ model-> u_role; $ Model-> attributes = $ _ POST [ 'Users']; if ($ model-> save ()) $ this-> redirect (array ( 'view', 'id' => $ model-> u_id)); } $ This-> render ( 'update', array ( 'model' => $ model,)); }

У поданні (views / users / _form.php) прибираємо з форми поле «Роль» для користувача у якого немає прав її змінювати.

... &lt;? Php if (Yii :: app () -> user-> checkAccess ( 'changeRole')) {?> <Div class = "row"> &lt;? Php echo $ form-> labelEx ($ model, 'u_role '); ?> &lt;? Php echo $ form-> dropDownList ($ model, 'u_role', array (Users :: ROLE_USER => Users :: ROLE_USER, Users :: ROLE_ADMIN => Users :: ROLE_ADMIN, Users :: ROLE_ROOT => Users :: ROLE_ROOT,)); ?> &lt;? Php echo $ form-> error ($ model, 'u_role'); ?> </ Div> &lt;? Php}?> ...

На цьому ми зупинимося. Загальну ідею, сподіваюся, я пояснив. Якщо є бажання, можете скачати архів і погратися з цим прикладом.

Source

В архіві є дамп бази і папка protected додатки. Сам додаток вам потрібно буде створити самостійно. Далі, думаю, ви розберетеся 😉

Будь-які питання або зауваження залишайте в коментарях. Постараюся відповісти!

Lt;?
Php if (Yii :: app () -> user-> checkAccess ( 'changeRole')) {?
Php echo $ form-> labelEx ($ model, 'u_role '); ?
Php echo $ form-> error ($ model, 'u_role'); ?
Php}?
Категории
  • Биология
  • Математика
  • Краеведению
  • Лечебная
  • Наука
  • Физике
  • Природоведение
  • Информатика
  • Новости

  • Новости
    https://banwar.org/
    Наша взаимовыгодная связь https://banwar.org/. Запустив новый сайт, "Пари Матч" обещает своим клиентам незабываемый опыт и возможность выиграть крупные суммы.


    Наши клиенты
    Клиенты

    Быстрая связь

    Тел.: (044) 587-84-78
    E-mail: [email protected]

    Имя:
    E-mail:
    Телефон:
    Вопрос\Комментарий: