Bouncer — это элегантный, независимый от платформы подход к управлению ролями и возможностями для любого приложения с использованием моделей Eloquent.
bouncer:clean
Bouncer — это элегантный, независимый от платформы подход к управлению ролями и возможностями для любого приложения с использованием моделей Eloquent. Благодаря выразительному и гибкому синтаксису он максимально не мешает вам: используйте его, когда хотите, и игнорируйте, когда не хотите.
Чтобы получить быстрый и понятный список функций Bouncer, ознакомьтесь с шпаргалкой.
Bouncer хорошо работает с другими возможностями, которые вы жестко запрограммировали в своем приложении. Ваш код всегда имеет приоритет: если ваш код допускает действие, Bouncer не будет вмешиваться.
После установки вы можете просто сказать вышибале, что вы хотите разрешить у ворот:
// Give a user the ability to create posts
Bouncer:: allow ( $ user )-> to ( ' create ' , Post::class);
// Alternatively, do it through a role
Bouncer:: allow ( ' admin ' )-> to ( ' create ' , Post::class);
Bouncer:: assign ( ' admin ' )-> to ( $ user );
// You can also grant an ability only to a specific model
Bouncer:: allow ( $ user )-> to ( ' edit ' , $ post );
Когда вы проверяете способности у ворот Ларавел, автоматически обращается к Bouncer. Если Bouncer увидит способность, предоставленную текущему пользователю (напрямую или через роль), он авторизует проверку.
Примечание . Для Bouncer v1.0.2 требуется PHP 8.2+ и Laravel/Eloquent 11+.
Если вы используете Laravel v6–v10, используйте Bouncer v1.0.1. Если вы используете Laravel v5.5–v5.8, используйте Bouncer RC6.
Установите Bouncer с помощью композитора:
composer require silber/bouncer
Добавьте черту Bouncer в вашу пользовательскую модель:
use Silber Bouncer Database HasRolesAndAbilities ;
class User extends Model
{
use HasRolesAndAbilities;
}
Теперь займемся миграцией Bouncer. Сначала опубликуйте миграции в каталоге migrations
вашего приложения, выполнив следующую команду:
php artisan vendor:publish --tag="bouncer.migrations"
Наконец, запустите миграцию:
php artisan migrate
Всякий раз, когда вы используете фасад Bouncer
в своем коде, не забудьте добавить эту строку в импорт пространства имен в верхней части файла:
use Bouncer ;
Дополнительную информацию о фасадах Laravel можно найти в документации Laravel.
Установите Bouncer с помощью композитора:
composer require silber/bouncer
Настройте базу данных с помощью компонента Eloquent Capsule:
use Illuminate Database Capsule Manager as Capsule ;
$ capsule = new Capsule ;
$ capsule -> addConnection ([ /* connection config */ ]);
$ capsule -> setAsGlobal ();
Более подробную информацию можно найти в документации Eloquent Capsule.
Запустите миграцию одним из следующих методов:
Используйте такой инструмент, как vagabond, для запуска миграции Laravel за пределами приложения Laravel. Вы найдете необходимые миграции в файле-заглушке миграций.
Альтернативно вы можете запустить необработанный SQL непосредственно в своей базе данных.
Добавьте черту Bouncer в вашу пользовательскую модель:
use Illuminate Database Eloquent Model ;
use Silber Bouncer Database HasRolesAndAbilities ;
class User extends Model
{
use HasRolesAndAbilities;
}
Создайте экземпляр Bouncer:
use Silber Bouncer Bouncer ;
$ bouncer = Bouncer:: create ();
// If you are in a request with a current user
// that you'd wish to check permissions for,
// pass that user to the "create" method:
$ bouncer = Bouncer:: create ( $ user );
Если вы используете внедрение зависимостей в своем приложении, вы можете зарегистрировать экземпляр Bouncer
как синглтон в контейнере:
use Silber Bouncer Bouncer ;
use Illuminate Container Container ;
Container:: getInstance ()-> singleton (Bouncer::class, function () {
return Bouncer:: create ();
});
Теперь вы можете внедрить Bouncer
в любой класс, которому он нужен.
Метод create
создает экземпляр Bouncer
с разумными настройками по умолчанию. Чтобы полностью настроить его, используйте метод make
для получения экземпляра фабрики. Вызовите create()
на фабрике, чтобы создать экземпляр Bouncer
:
use Silber Bouncer Bouncer ;
$ bouncer = Bouncer:: make ()
-> withCache ( $ customCacheInstance )
-> create ();
Посетите класс Factory
, чтобы увидеть все доступные настройки.
Укажите, какая модель будет использоваться в качестве модели пользователя во всем вашем приложении:
$ bouncer -> useUserModel (User::class);
Для дополнительной настройки ознакомьтесь с разделом «Конфигурация» ниже.
По умолчанию запросы Bouncer кэшируются для текущего запроса. Для повышения производительности вы можете включить кэширование перекрестных запросов.
Добавление ролей и способностей пользователей стало чрезвычайно простым. Вам не нужно заранее создавать роль или способность. Просто передайте имя роли/способности, и Bouncer создаст ее, если она не существует.
Примечание. Во всех приведенных ниже примерах используется фасад
Bouncer
. Если вы не используете фасады, вместо этого вы можете внедрить в свой класс экземплярSilberBouncerBouncer
.
Давайте создадим роль admin
и предоставим ей возможность ban-users
на нашем сайте:
Bouncer:: allow ( ' admin ' )-> to ( ' ban-users ' );
Вот и все. За кулисами Bouncer создаст для вас и образец Role
, и модель Ability
.
Если вы хотите добавить к роли/способности дополнительные атрибуты, такие как удобочитаемый заголовок, вы можете создать их вручную, используя методы role
и ability
класса Bouncer
:
$ admin = Bouncer:: role ()-> firstOrCreate ([
' name ' => ' admin ' ,
' title ' => ' Administrator ' ,
]);
$ ban = Bouncer:: ability ()-> firstOrCreate ([
' name ' => ' ban-users ' ,
' title ' => ' Ban users ' ,
]);
Bouncer:: allow ( $ admin )-> to ( $ ban );
Чтобы теперь предоставить пользователю роль admin
, просто сообщите вышибале, что данному пользователю должна быть назначена роль администратора:
Bouncer:: assign ( ' admin ' )-> to ( $ user );
Альтернативно вы можете вызвать метод assign
непосредственно у пользователя:
$ user -> assign ( ' admin ' );
Иногда вам может потребоваться предоставить пользователю возможность напрямую, без использования роли:
Bouncer:: allow ( $ user )-> to ( ' ban-users ' );
Здесь вы также можете сделать то же самое непосредственно за пределами пользователя:
$ user -> allow ( ' ban-users ' );
Иногда вам может потребоваться ограничить возможность определенным типом модели. Просто передайте имя модели в качестве второго аргумента:
Bouncer:: allow ( $ user )-> to ( ' edit ' , Post::class);
Если вы хотите ограничить эту возможность конкретным экземпляром модели, вместо этого передайте реальную модель:
Bouncer:: allow ( $ user )-> to ( ' edit ' , $ post );
Используйте метод toOwn
, чтобы позволить пользователям управлять своими собственными моделями:
Bouncer:: allow ( $ user )-> toOwn (Post::class);
Теперь при проверке на входе, может ли пользователь выполнить действие над данным сообщением, user_id
сообщения будет сравниваться с id
вошедшего в систему пользователя (это можно настроить). Если они совпадают, ворота разрешат действие.
Вышеупомянутое предоставит все способности «принадлежащим» пользователю моделям. Вы можете ограничить возможности, вызвав метод to
:
Bouncer:: allow ( $ user )-> toOwn (Post::class)-> to ( ' view ' );
// Or pass it an array of abilities:
Bouncer:: allow ( $ user )-> toOwn (Post::class)-> to ([ ' view ' , ' update ' ]);
Вы также можете разрешить пользователям владеть всеми типами моделей в вашем приложении:
Bouncer:: allow ( $ user )-> toOwnEverything ();
// And to restrict ownership to a given ability
Bouncer:: allow ( $ user )-> toOwnEverything ()-> to ( ' view ' );
Вышибала также может отозвать ранее назначенную пользователю роль:
Bouncer:: retract ( ' admin ' )-> from ( $ user );
Или сделайте это непосредственно на пользователе:
$ user -> retract ( ' admin ' );
Вышибала также может удалить ранее предоставленную пользователю способность:
Bouncer:: disallow ( $ user )-> to ( ' ban-users ' );
Или непосредственно на пользователе:
$ user -> disallow ( ' ban-users ' );
Примечание. Если у пользователя есть роль, позволяющая ему
ban-users
, у него все равно будет такая возможность. Чтобы запретить это, либо удалите возможность из роли, либо отзовите роль у пользователя.
Если способность была предоставлена через роль, попросите вышибалу вместо этого удалить способность из роли:
Bouncer:: disallow ( ' admin ' )-> to ( ' ban-users ' );
Чтобы удалить возможность для определенного типа модели, передайте ее имя в качестве второго аргумента:
Bouncer:: disallow ( $ user )-> to ( ' delete ' , Post::class);
Предупреждение: если у пользователя есть возможность
delete
конкретный экземпляр$post
, приведенный выше код не удалит эту возможность. Вам придется удалить эту возможность отдельно, передав фактический$post
в качестве второго аргумента, как показано ниже.
Чтобы удалить возможность для конкретного экземпляра модели, вместо этого передайте реальную модель:
Bouncer:: disallow ( $ user )-> to ( ' delete ' , $ post );
Примечание . Метод
disallow
удаляет только те способности, которые ранее были предоставлены этому пользователю/роли. Если вы хотите запретить часть того, что разрешено более общей способностью, используйте методforbid
.
Bouncer также позволяет вам forbid
определенную способность для более детального контроля. Иногда вам может потребоваться предоставить пользователю/роли возможность, охватывающую широкий диапазон действий, но затем ограничить небольшое подмножество этих действий.
Вот несколько примеров:
Вы можете разрешить пользователю просматривать все документы, но у вас есть конкретный строго секретный документ, просмотр которого ему не должен быть разрешен:
Bouncer:: allow ( $ user )-> to ( ' view ' , Document::class);
Bouncer:: forbid ( $ user )-> to ( ' view ' , $ classifiedDocument );
Возможно, вы захотите разрешить вашим superadmin
делать все в вашем приложении, включая добавление/удаление пользователей. Тогда у вас может быть роль admin
, которая может делать все, кроме управления пользователями:
Bouncer:: allow ( ' superadmin ' )-> everything ();
Bouncer:: allow ( ' admin ' )-> everything ();
Bouncer:: forbid ( ' admin ' )-> toManage (User::class);
Возможно, вы захотите время от времени блокировать пользователей, лишая их доступа ко всем способностям. Однако фактическое удаление всех их ролей и способностей будет означать, что после снятия запрета нам придется выяснить, каковы были их первоначальные роли и способности.
Использование запрещенной способности означает, что они могут сохранить все свои существующие роли и способности, но при этом не иметь никаких полномочий. Мы можем добиться этого, создав специальную banned
роль, для которой запретим все:
Bouncer:: forbid ( ' banned ' )-> everything ();
Затем, когда мы хотим заблокировать пользователя, мы назначаем ему роль banned
:
Bouncer:: assign ( ' banned ' )-> to ( $ user );
Чтобы снять бан, просто отзовем роль у пользователя:
Bouncer:: retract ( ' banned ' )-> from ( $ user );
Как видите, запрещенные способности Bouncer дают вам детальный контроль над разрешениями в вашем приложении.
Чтобы удалить запрещенную способность, используйте метод unforbid
:
Bouncer:: unforbid ( $ user )-> to ( ' view ' , $ classifiedDocument );
Примечание : это удалит любую ранее запрещенную способность. Эта способность не будет автоматически разрешена, если она еще не разрешена другой обычной способностью, предоставленной этому пользователю/роли.
Примечание . Вообще говоря, вам не нужно проверять роли напрямую. Лучше разрешить роли определенные способности, а затем вместо этого проверять наличие этих способностей. Если то, что вам нужно, носит очень общий характер, вы можете создать очень широкие способности. Например, возможность
access-dashboard
всегда лучше, чем прямая проверка ролейadmin
илиeditor
. В тех редких случаях, когда вам нужно проверить роль, эта функция доступна здесь.
Вышибала может проверить, имеет ли пользователь определенную роль:
Bouncer:: is ( $ user )-> a ( ' moderator ' );
Если проверяемая роль начинается с гласной, возможно, вы захотите использовать метод an
:
Bouncer:: is ( $ user )-> an ( ' admin ' );
В обратном случае вы также можете проверить, нет ли у пользователя определенной роли:
Bouncer:: is ( $ user )-> notA ( ' moderator ' );
Bouncer:: is ( $ user )-> notAn ( ' admin ' );
Вы можете проверить, имеет ли пользователь одну из многих ролей:
Bouncer:: is ( $ user )-> a ( ' moderator ' , ' editor ' );
Вы также можете проверить, есть ли у пользователя все заданные роли:
Bouncer:: is ( $ user )-> all ( ' editor ' , ' moderator ' );
Вы также можете проверить, нет ли у пользователя ни одной из заданных ролей:
Bouncer:: is ( $ user )-> notAn ( ' editor ' , ' moderator ' );
Эти проверки также можно выполнить непосредственно у пользователя:
$ user -> isAn ( ' admin ' );
$ user -> isA ( ' subscriber ' );
$ user -> isNotAn ( ' admin ' );
$ user -> isNotA ( ' subscriber ' );
$ user -> isAll ( ' editor ' , ' moderator ' );
Вы можете запросить у своих пользователей, имеют ли они определенную роль:
$ users = User:: whereIs ( ' admin ' )-> get ();
Вы также можете передать несколько ролей, чтобы запросить пользователей, имеющих любую из заданных ролей:
$ users = User:: whereIs ( ' superadmin ' , ' admin ' )-> get ();
Чтобы запросить пользователей, обладающих всеми заданными ролями, используйте whereIsAll
:
$ users = User:: whereIsAll ( ' sales ' , ' marketing ' )-> get ();
Вы можете получить все роли для пользователя непосредственно из модели пользователя:
$ roles = $ user -> getRoles ();
Вы можете получить все возможности пользователя непосредственно из модели пользователя:
$ abilities = $ user -> getAbilities ();
Это вернет коллекцию разрешенных способностей пользователя, включая любые способности, предоставленные пользователю через его роли.
Вы также можете получить список способностей, которые были явно запрещены:
$ forbiddenAbilities = $ user -> getForbiddenAbilities ();
Авторизация пользователей выполняется непосредственно в Laravel's Gate
или в модели пользователя ( $user->can($ability)
).
Для удобства класс Bouncer
предоставляет следующие сквозные методы:
Bouncer:: can ( $ ability );
Bouncer:: can ( $ ability , $ model );
Bouncer:: canAny ( $ abilities );
Bouncer:: canAny ( $ abilities , $ model );
Bouncer:: cannot ( $ ability );
Bouncer:: cannot ( $ ability , $ model );
Bouncer:: authorize ( $ ability );
Bouncer:: authorize ( $ ability , $ model );
Они вызывают непосредственно эквивалентные методы класса Gate
.
Bouncer не добавляет свои собственные блейд-директивы. Поскольку Bouncer работает напрямую с шлюзом Laravel, просто используйте его директиву @can
чтобы проверить способности текущего пользователя:
@can ('update', $post)
< a href =" {{ route('post.update', $post) }} " > Edit Post </ a >
@endcan
Поскольку прямая проверка ролей обычно не рекомендуется, Bouncer не поставляется с отдельной директивой для этого. Если вы все еще настаиваете на проверке ролей, вы можете сделать это с помощью общей директивы @if
:
@ if ( $ user -> isAn ( ' admin ' ))
//
@endif
Все запросы, выполняемые Bouncer, кэшируются для текущего запроса. Если вы включите кэширование перекрестных запросов, кеш будет сохраняться для разных запросов.
Когда вам понадобится, вы можете полностью обновить кеш баунсера:
Bouncer:: refresh ();
Примечание. При полном обновлении кеша для всех пользователей используются теги кеша, если они доступны. Не все драйверы кэша поддерживают это. Обратитесь к документации Laravel, чтобы узнать, поддерживает ли ваш драйвер теги кэша. Если ваш драйвер не поддерживает теги кэша, вызов
refresh
может быть немного медленным, в зависимости от количества пользователей в вашей системе.
Альтернативно вы можете обновить кеш только для конкретного пользователя:
Bouncer:: refreshFor ( $ user );
Примечание . При использовании областей с несколькими арендаторами кэш обновится только для пользователя в контексте текущей области. Чтобы очистить кэшированные данные для того же пользователя в контексте другой области, его необходимо вызвать из этой области.
Bouncer полностью поддерживает мультитенантные приложения, что позволяет легко интегрировать роли и возможности Bouncer для всех арендаторов в одном приложении.
Чтобы начать, сначала опубликуйте промежуточное программное обеспечение области в своем приложении:
php artisan vendor:publish --tag="bouncer.middleware"
Промежуточное ПО теперь будет опубликовано в app/Http/Middleware/ScopeBouncer.php
. В этом промежуточном программном обеспечении вы указываете Bouncer, какой арендатор использовать для текущего запроса. Например, если предположить, что у всех ваших пользователей есть атрибут account_id
, вот как будет выглядеть ваше промежуточное ПО:
public function handle ( $ request , Closure $ next )
{
$ tenantId = $ request -> user ()-> account_id ;
Bouncer:: scope ()-> to ( $ tenantId );
return $ next ( $ request );
}
Вы, конечно, можете изменить это промежуточное программное обеспечение в соответствии с потребностями вашего приложения, например, получить информацию о клиенте из поддомена и т. д.
Теперь, когда промежуточное программное обеспечение установлено, обязательно зарегистрируйте его в своем HTTP-ядре:
protected $ middlewareGroups = [
' web ' => [
// Keep the existing middleware here, and add this:
App Http Middleware ScopeBouncer::class,
]
];
Все запросы Bouncer теперь будут ограничены данным клиентом.
В зависимости от настройки вашего приложения вы, возможно, не захотите, чтобы все запросы ограничивались текущим клиентом. Например, у вас может быть фиксированный набор ролей/возможностей, одинаковый для всех арендаторов, и вы позволяете пользователям только контролировать, каким пользователям какие роли назначены и какие роли имеют какие способности. Чтобы добиться этого, вы можете указать области действия Bouncer ограничивать только отношения между моделями Bouncer, но не сами модели:
Bouncer:: scope ()-> to ( $ tenantId )-> onlyRelations ();
Более того, ваше приложение может даже не позволять пользователям контролировать, какие способности имеет данная роль. В этом случае укажите области действия Bouncer исключить возможности ролей из области, чтобы эти отношения оставались глобальными для всех клиентов:
Bouncer:: scope ()-> to ( $ tenantId )-> onlyRelations ()-> dontScopeRoleAbilities ();
Если ваши потребности еще более специализированы, чем описано выше, вы можете создать свою собственную Scope
с любой необходимой вам логикой:
use Silber Bouncer Contracts Scope ;
class MyScope implements Scope
{
// Whatever custom logic your app needs
}
Затем в поставщике услуг зарегистрируйте свою пользовательскую область:
Bouncer:: scope ( new MyScope );
Bouncer будет вызывать методы интерфейса Scope
на различных этапах своего выполнения. Вы можете обращаться с ними в соответствии с вашими конкретными потребностями.
Bouncer поставляется с разумными настройками по умолчанию, поэтому в большинстве случаев нет необходимости в какой-либо настройке. Для более детального управления Bouncer можно настроить, вызвав различные методы конфигурации класса Bouncer
.
Если вы используете только один или два из этих параметров конфигурации, вы можете вставить их в основной метод boot
AppServiceProvider
. Если они начнут расти, вы можете создать отдельный класс BouncerServiceProvider
в каталоге вашего app/Providers
(не забудьте зарегистрировать его в массиве конфигурации providers
).
По умолчанию все запросы, выполняемые Bouncer, кэшируются для текущего запроса. Для повышения производительности вы можете использовать кэширование перекрестных запросов:
Bouncer:: cache ();
Предупреждение: если вы включаете кэширование перекрестных запросов, вы несете ответственность за обновление кеша всякий раз, когда вы вносите изменения в роли/возможности пользователя. О том, как обновить кеш, читайте Обновление кеша.
Напротив, иногда вам может потребоваться полностью отключить кеш даже в рамках одного запроса:
Bouncer:: dontCache ();
Это особенно полезно в модульных тестах, когда вы хотите выполнить утверждения для только что предоставленных ролей/способностей.
Чтобы изменить имена таблиц базы данных, используемые Bouncer, передайте ассоциативный массив методу tables
. Ключами должны быть имена таблиц Bouncer по умолчанию, а значениями должны быть имена таблиц, которые вы хотите использовать. Вам не обязательно передавать имена всех таблиц; только те, которые вы хотите изменить.
Bouncer:: tables ([
' abilities ' => ' my_abilities ' ,
' permissions ' => ' granted_abilities ' ,
]);
Опубликованная миграция Bouncer использует имена таблиц из этой конфигурации, поэтому убедитесь, что они установлены перед фактическим запуском миграции.
Вы можете легко расширить встроенные модели Role
и Ability
Bouncer:
namespace App Models ;
use Silber Bouncer Database Ability as BouncerAbility ;
class Ability extends BouncerAbility
{
// custom code
}
namespace App Models ;
use Silber Bouncer Database Role as BouncerRole ;
class Role extends BouncerRole
{
// custom code
}
В качестве альтернативы вы можете использовать черты IsAbility
и IsRole
Bouncer, фактически не расширяя какую-либо из моделей Bouncer:
namespace App Models ;
use Illuminate Database Eloquent Model ;
use Silber Bouncer Database Concerns IsAbility ;
class Ability extends Model
{
use IsAbility;
// custom code
}
namespace App Models ;
use Illuminate Database Eloquent Model ;
use Silber Bouncer Database Concerns IsRole ;
class Role extends Model
{
use IsRole;
// custom code
}
Если вы используете черты вместо расширения моделей Bouncer, обязательно самостоятельно установите правильное имя $table
и поля $fillable
.
Независимо от того, какой метод вы используете, следующим шагом будет указание Bouncer использовать ваши пользовательские модели:
Bouncer:: useAbilityModel ( App Models Ability::class);
Bouncer:: useRoleModel ( App Models Role::class);
Примечание . Eloquent определяет внешний ключ отношений на основе имени родительской модели (см. документацию Eloquent). Для простоты назовите свои пользовательские классы так же, как у Bouncer:
Ability
иRole
соответственно.Если вам нужно использовать разные имена, обязательно либо обновите файл миграции, либо переопределите методы связи, чтобы явно задать их внешние ключи.
По умолчанию Bouncer автоматически использует пользовательскую модель защиты аутентификации по умолчанию.
Если вы используете Bouncer с защитой, отличной от стандартной, и он использует другую модель пользователя, вы должны сообщить Bouncer о модели пользователя, которую вы хотите использовать:
Bouncer:: useUserModel ( App Admin::class);
В Bouncer концепция владения используется, чтобы позволить пользователям выполнять действия над моделями, которыми они «владеют».
По умолчанию Bouncer сверяет user_id
модели с первичным ключом текущего пользователя. При необходимости для него можно установить другой атрибут:
Bouncer:: ownedVia ( ' userId ' );
Если разные модели используют разные столбцы для владения, вы можете зарегистрировать их отдельно:
Bouncer:: ownedVia (Post::class, ' created_by ' );
Bouncer:: ownedVia (Order::class, ' entered_by ' );
Для большего контроля вы можете передать замыкание со своей собственной логикой:
Bouncer:: ownedVia (Game::class, function ( $ game , $ user ) {
return $ game -> team_id == $ user -> team_id ;
});
В Bouncer есть некоторые концепции, о которых люди продолжают задавать вопросы, поэтому вот краткий список некоторых из этих тем:
Раздачу начальных ролей и способностей можно выполнить в обычном классе раздачи Laravel. Начните с создания специального файла раздачи для Bouncer:
php artisan make:seeder BouncerSeeder
Поместите весь код раздающих ролей и способностей в метод run
раздающего устройства. Вот пример того, как это может выглядеть:
use Bouncer ;
use Illuminate Database Seeder ;
class BouncerSeeder extends Seeder
{
public function run ()
{
Bouncer:: allow ( ' superadmin ' )-> everything ();
Bouncer:: allow ( ' admin ' )-> everything ();
Bouncer:: forbid ( ' admin ' )-> toManage (User::class);
Bouncer:: allow ( ' editor ' )-> to ( ' create ' , Post::class);
Bouncer:: allow ( ' editor ' )-> toOwn (Post::class);
// etc.
}
}
Чтобы запустить его, передайте имя класса сеялки в параметр class
команды db:seed
:
php artisan db:seed --class=BouncerSeeder
scope
Bouncer можно использовать для разделения различных частей сайта, создавая для каждой из них изолированную зону со своим собственным набором ролей и способностей:
Создайте промежуточное программное обеспечение ScopeBouncer
, которое принимает $identifier
и устанавливает его в качестве текущей области:
use Bouncer , Closure ;
class ScopeBouncer
{
public function handle ( $ request , Closure $ next , $ identifier )
{
Bouncer:: scope ()-> to ( $ identifier );
return $ next ( $ request );
}
}
Зарегистрируйте это новое промежуточное программное обеспечение в качестве промежуточного программного обеспечения маршрута в классе ядра HTTP:
protected $ routeMiddleware = [
// Keep the other route middleware, and add this:
' scope-bouncer ' => App Http Middleware ScopeBouncer::class,
];
У вашего поставщика услуг маршрутизации примените это промежуточное программное обеспечение с другим идентификатором для общедоступных маршрутов и маршрутов панели мониторинга соответственно:
Route:: middleware ([ ' web ' , ' scope-bouncer:1 ' ])
-> namespace ( $ this -> namespace )
-> group ( base_path ( ' routes/public.php ' ));
Route:: middleware ([ ' web ' , ' scope-bouncer:2 ' ])
-> namespace ( $ this -> namespace )
-> group ( base_path ( ' routes/dashboard.php ' ));
Вот и все. Все роли и способности теперь будут распределяться отдельно для каждого раздела вашего сайта. Чтобы точно настроить область действия, см. раздел Настройка области действия Bouncer.
Начиная с Laravel 5.4, набор символов базы данных по умолчанию теперь utf8mb4
. Если вы используете более старые версии некоторых баз данных (MySQL ниже 5.7.7 или MariaDB ниже 10.2.2) с Laravel 5.4+, вы получите ошибку SQL при попытке создать индекс для строкового столбца. Чтобы это исправить, измените длину строки Laravel по умолчанию в вашем AppServiceProvider
:
use Illuminate Support Facades Schema ;
public function boot ()
{
Schema:: defaultStringLength ( 191 );
}
Вы можете прочитать больше в этой статье новостей Laravel.
Столбцы JSON — относительно новое дополнение к MySQL (5.7.8) и MariaDB (10.2.7). Если вы используете более старую версию этих баз данных, вы не можете использовать столбцы JSON.
Лучшим решением будет обновление вашей БД. Если в настоящее время это невозможно, вы можете изменить опубликованный файл миграции, чтобы вместо него использовался text
столбец:
- $table->json('options')->nullable();
+ $table->text('options')->nullable();
bouncer:clean
Команда bouncer:clean
удаляет неиспользуемые способности. Выполнение этой команды удалит 2 типа неиспользуемых способностей:
Неназначенные способности — способности, которые никому не назначены. Например:
Bouncer:: allow ( $ user )-> to ( ' view ' , Plan::class);
Bouncer:: disallow ( $ user )-> to ( ' view ' , Plan::class);
На данный момент возможность «просмотр планов» никому не назначена, поэтому она будет удалена.
Примечание . В зависимости от контекста вашего приложения вы можете не захотеть их удалять. Если вы разрешаете пользователям управлять способностями в пользовательском интерфейсе вашего приложения, вы, вероятно, не захотите удалять неназначенные способности. См. ниже.
Осиротевшие способности - способности моделей, модели которых были удалены:
Bouncer:: allow ( $ user )-> to ( ' delete ' , $ plan );
$ plan -> delete ();
Поскольку план больше не существует, эта способность больше не имеет смысла, поэтому она будет удалена.
Если вы хотите удалить только один тип неиспользуемой способности, запустите ее с одним из следующих флагов:
php artisan bouncer:clean --unassigned
php artisan bouncer:clean --orphaned
Если вы не передадите ему никаких флагов, он удалит оба типа неиспользуемых способностей.
Чтобы периодически запускать эту команду автоматически, добавьте ее в расписание ядра консоли:
$ schedule -> command ( ' bouncer:clean ' )-> weekly ();
// Adding abilities for users
Bouncer:: allow ( $ user )-> to ( ' ban-users ' );
Bouncer:: allow ( $ user )-> to ( ' edit ' , Post::class);
Bouncer:: allow ( $ user )-> to ( ' delete ' , $ post );
Bouncer:: allow ( $ user )-> everything ();
Bouncer:: allow ( $ user )-> toManage (Post::class);
Bouncer:: allow ( $ user )-> toManage ( $ post );
Bouncer:: allow ( $ user )-> to ( ' view ' )-> everything ();
Bouncer:: allow ( $ user )-> toOwn (Post::class);
Bouncer:: allow ( $ user )-> toOwnEverything ();
// Removing abilities uses the same syntax, e.g.
Bouncer:: disallow ( $ user )-> to ( ' delete ' , $ post );
Bouncer:: disallow ( $ user )-> toManage (Post::class);
Bouncer:: disallow ( $ user )-> toOwn (Post::class);
// Adding & removing abilities for roles
Bouncer:: allow ( ' admin ' )-> to ( ' ban-users ' );
Bouncer:: disallow ( ' admin ' )-> to ( ' ban-users ' );
// You can also forbid specific abilities with the same syntax...
Bouncer:: forbid ( $ user )-> to ( ' delete ' , $ post );
// And also remove a forbidden ability with the same syntax...
Bouncer:: unforbid ( $ user )-> to ( ' delete ' , $ post );
// Re-syncing a user's abilities
Bouncer:: sync ( $ user )-> abilities ( $ abilities );
// Assigning & retracting roles from users
Bouncer:: assign ( ' admin ' )-> to ( $ user );
Bouncer:: retract ( ' admin ' )-> from ( $ user );
// Assigning roles to multiple users by ID
Bouncer:: assign ( ' admin ' )-> to ([ 1 , 2 , 3 ]);
// Re-syncing a user's roles
Bouncer:: sync ( $ user )-> roles ( $ roles );
// Checking the current user's abilities
$ boolean = Bouncer:: can ( ' ban-users ' );
$ boolean = Bouncer:: can ( ' edit ' , Post::class);
$ boolean = Bouncer:: can ( ' delete ' , $ post );
$ boolean = Bouncer:: cannot ( ' ban-users ' );
$ boolean = Bouncer:: cannot ( ' edit ' , Post::class);
$ boolean = Bouncer:: cannot ( ' delete ' , $ post );
// Checking a user's roles
$ boolean = Bouncer:: is ( $ user )-> a ( ' subscriber ' );
$ boolean = Bouncer:: is ( $ user )-> an ( ' admin ' );
$ boolean = Bouncer:: is ( $ user )-> notA ( ' subscriber ' );
$ boolean = Bouncer:: is ( $ user )-> notAn ( ' admin ' );
$ boolean = Bouncer:: is ( $ user )-> a ( ' moderator ' , ' editor ' );
$ boolean = Bouncer:: is ( $ user )-> all ( ' moderator ' , ' editor ' );
Bouncer:: cache ();
Bouncer:: dontCache ();
Bouncer:: refresh ();
Bouncer:: refreshFor ( $ user );
Некоторые из этих функций также доступны непосредственно в модели пользователя:
$ user -> allow ( ' ban-users ' );
$ user -> allow ( ' edit ' , Post::class);
$ user -> allow ( ' delete ' , $ post );
$ user -> disallow ( ' ban-users ' );
$ user -> disallow ( ' edit ' , Post::class);
$ user -> disallow ( ' delete ' , $ post );
$ user -> assign ( ' admin ' );
$ user -> retract ( ' admin ' );
$ boolean = $ user -> isAn ( ' admin ' );
$ boolean = $ user -> isAn ( ' editor ' , ' moderator ' );
$ boolean = $ user -> isAll ( ' moderator ' , ' editor ' );
$ boolean = $ user -> isNotAn ( ' admin ' , ' moderator ' );
// Querying users by their roles
$ users = User:: whereIs ( ' superadmin ' )-> get ();
$ users = User:: whereIs ( ' superadmin ' , ' admin ' )-> get ();
$ users = User:: whereIsAll ( ' sales ' , ' marketing ' )-> get ();
$ abilities = $ user -> getAbilities ();
$ forbidden = $ user -> getForbiddenAbilities ();
Среди миллионов пакетов, которые Спати так любезно подарил сообществу, вы найдете отличный пакет laravel-permission. Как и Bouncer, он прекрасно интегрируется со встроенными средствами проверки разрешений и шлюзов Laravel, но имеет другой набор вариантов дизайна, когда дело касается синтаксиса, структуры и функций БД.
Bouncer — это программное обеспечение с открытым исходным кодом, лицензированное по лицензии MIT.