Я пишу многопользовательский код. Имеют разные уровни доступа, например, администратор и пользователь. Администратор имеет больше привилегий, чем обычный пользователь, и наоборот. Использование Codeigniter в качестве фреймворка, но переход к фреймворку Laravel для следующего проекта. Теперь, если у меня есть функция, например,
function editSomething()
{
$book_id = new Book();
$id = $this->input-post('id');
// and then simply,
if($book->where('id', $id)->update($data))
}
Очевидно, что нет проверки на кто (пользователь) СООБЩЕНИЕИнг идентификатор. Это может быть что угодно HTTP: // локальный / Foo = бар и bam контроллер выполнит.
Я пытаюсь понять, что в такой среде, как я могу защитить свои функции от несанкционированного доступа, предоставляет ли инфраструктура мне какие-либо средства защиты или инструкции, чтобы сделать это, так что это будет моей логикой, чтобы проверить владельца элемента и затем обновить соответственно. Означает ли это, что для всех записей в БД я должен сохранять owner_id (или что-то в этом роде), чтобы определить владельца записи?
Мне трудно понять концепцию здесь, поэтому любые рекомендации будут оценены.
Благодарю.
Это зависит от того, насколько плотно вы хотите контролировать доступ к ресурсу.
Например, вы можете хотеть иметь одну группу пользователей, которые могут обновлять любые сообщения, но вы также можете хотеть иметь некоторых пользователей, которые могут редактировать только свои собственные сообщения. Если вам нужно последнее, то вы захотите сохранить столбец владельца в таблице ресурса. Это хорошая практика в целом; даже если вы не используете его для контроля доступа, хорошо бы иметь возможность проверять, кто создал ресурс. Вы даже можете создавать контрольные таблицы, чтобы отслеживать, когда объекты изменяются и кем.
В вашей таблице пользователей вы можете сопоставить пользователей с ролями (для более сложной системы создайте отдельную сводку users_roles), и тогда любая используемая вами система управления auth / login / session (как правило, предоставляется платформой) должна иметь способ проверить роль текущего пользователя. Затем вы можете назначить разрешения для каждой роли. Пример схемы может быть что-то вроде:
|Users | |User_Role | |Permissions |
------------ -------------- |Roles | ----------------
|id | ==== |user_id | ------- |id |
|... | |role_id | ===== |id |===|role_id |
---------- ------------ |name | |resource |
------ |action |
--------------
Затем можно добавить условие, чтобы проверить, имеет ли зарегистрированный пользователь правильные разрешения в действиях контроллера, которые необходимо защитить.
Некоторые фреймворки, включая Laravel, позволяют применять фильтры к маршрутам или контроллерам. Посмотреть здесь: http://laravel.com/docs/4.2/routing#route-filters. Это поможет вам избежать копирования одной и той же логики аутентификации в несколько методов контроллера.
Помимо добавления идентификатора владельца в каждой таблице, это также делается по-другому? Я думаю, что это не конкретная структура, а концепция, которую нужно понять в целом.
Я думаю, что это сильно зависит от отношения пользователя и его таблицы к другим сущностям и их вспомогательным таблицам. В некоторых случаях имеет смысл добавить user_id в таблицу для обозначения владельца. Это, однако, может быть ограничивающим … Что если вы хотите защитить вещи, которые не являются реальными объектами, поддерживаемыми базой данных в системе (например, контроллеры или действия)? Если вы ищете что-то надежное, я бы порекомендовал использовать набор универсальных таблиц ACL, очень похожих на @bencohenbaritone, за исключением того факта, что он пропустил таблицу ресурсов:
Эта схема довольно проста, так как она не допускает вложенных или сгруппированных ролей, но дает вам идею. Теперь, основываясь на этом, можно создать службу, которая получает ресурс, разрешение и пользователя или роль и оценивает, может ли операция быть выполнена. Это может выглядеть примерно так:
$acl = $dic->getService('acl');
if ($acl->isAllowed($userOrRole, $resource, $perm)) {
// do stuff!
} else {
throw new Exception('You do not have access to perform this operation.', 403);
}
Вы могли бы реализовать это фильтр запросов, в контроллере или где-то еще вообще. Это действительно зависит от типа ресурса и ваших бизнес-правил.
Как правило, вы бы применили концепцию ACL / RBAC к этой проблеме. Вещи в вашей системе, которые должны быть защищены с различными уровнями доступа, будут ресурсами. Пользователи будут иметь одну или несколько ролей. Каждая роль будет иметь набор разрешений для данного ресурса.
То, как вы храните и проверяете эту информацию, более или менее зависит от вас, но, как правило, она не встроена в каркас по умолчанию, кроме базовой аутентификации и иногда базовых файловых систем, таких как разрешения (часто в сочетании с аутентификацией).
Возможно, вы захотите взглянуть на Zend Framework и Zend Framework 2 для примеров реализации библиотеки ACL.
Zend_Acl
Zend\Permissions\Acl
Zend\Permissions\Rbac
С любым из них вам все равно нужно будет решить, где и как вы хотите проверить соответствие ACL и что вы хотите сделать Ресурсы.
У Laravel есть такая аутентификация встроенный, вам просто нужно добавить метод, как isAdmin()
на ваш User
возьмите объект и используйте его так:
<?php
function editSomething()
{
if (!Auth::user()->isAdmin())
App::abort(403);
...
Концепция будет аналогичной для CodeIgniter. Я не так хорошо знаком с CodeIgniter, но, насколько я могу судить, вам, вероятно, понадобится сторонняя библиотека, подобная этой:
Для аутентификации я использую Ion Auth и всю навигацию, подменю и т. д. я помещаю в отдельный файл конфигурации. Это выглядит как:
$config["nav"]["ajax_table/show_sport"] =
array(
"permission" => "100",
"subnav" => "FALSE",
"label" => lang("show_sport"),
"location" => "c=ajax_table&m=show_sport",
"parent_id" => "ajax_table");
Важной частью для вас является: разрешение. Я расширил таблицу «groups» с помощью столбца с названием «Разрешение», в котором для каждой роли я поставил значение. В моем примере 100 — обычный пользователь, 1000 — администратор.
В моем базовом контроллере я проверяю каждый запрос:
$this->navigation = $this->config->item("nav");
$role = $this->ion_auth_model->get_role();
if ($this->role < $this->navigation[$this->router->class . "/" . $this->router->method]["permission"]){
redirect("your/url/here", "refresh");
}
Вот и все.