Bouncer es un enfoque elegante e independiente del marco para gestionar roles y habilidades para cualquier aplicación que utilice modelos Eloquent.
bouncer:clean
Bouncer es un enfoque elegante e independiente del marco para gestionar roles y habilidades para cualquier aplicación que utilice modelos Eloquent. Con una sintaxis expresiva y fluida, se mantiene lo más apartado posible: úsalo cuando quieras, ignóralo cuando no.
Para obtener una lista rápida y fácil de ver de las funciones de Bouncer, consulte la hoja de referencia.
Bouncer funciona bien con otras habilidades que tienes codificadas en tu propia aplicación. Tu código siempre tiene prioridad: si tu código permite una acción, Bouncer no interferirá.
Una vez instalado, simplemente puede decirle al portero qué desea permitir en la puerta:
// 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 );
Cuando compruebes las habilidades en la puerta de Laravel, se consultará automáticamente a Bouncer. Si Bouncer ve una habilidad que se le ha otorgado al usuario actual (ya sea directamente o a través de un rol), autorizará la verificación.
Nota : Bouncer v1.0.2 requiere PHP 8.2+ y Laravel/Eloquent 11+.
Si estás en Laravel v6-v10, usa Bouncer v1.0.1. Si estás en Laravel v5.5-v5.8, usa Bouncer RC6.
Instale Bouncer con compositor:
composer require silber/bouncer
Agregue el rasgo de Bouncer a su modelo de usuario:
use Silber Bouncer Database HasRolesAndAbilities ;
class User extends Model
{
use HasRolesAndAbilities;
}
Ahora, para ejecutar las migraciones de Bouncer. Primero publique las migraciones en el directorio migrations
de su aplicación ejecutando el siguiente comando:
php artisan vendor:publish --tag="bouncer.migrations"
Finalmente, ejecute las migraciones:
php artisan migrate
Siempre que utilices la fachada Bouncer
en tu código, recuerda agregar esta línea a las importaciones de tu espacio de nombres en la parte superior del archivo:
use Bouncer ;
Para obtener más información sobre Laravel Facades, consulte la documentación de Laravel.
Instale Bouncer con compositor:
composer require silber/bouncer
Configure la base de datos con el componente Eloquent Capsule:
use Illuminate Database Capsule Manager as Capsule ;
$ capsule = new Capsule ;
$ capsule -> addConnection ([ /* connection config */ ]);
$ capsule -> setAsGlobal ();
Consulte la documentación de Eloquent Capsule para obtener más detalles.
Ejecute las migraciones mediante cualquiera de los siguientes métodos:
Utilice una herramienta como vagabond para ejecutar migraciones de Laravel fuera de una aplicación de Laravel. Encontrará las migraciones necesarias en el archivo auxiliar de migraciones.
Alternativamente, puede ejecutar el SQL sin formato directamente en su base de datos.
Agregue el rasgo de Bouncer a su modelo de usuario:
use Illuminate Database Eloquent Model ;
use Silber Bouncer Database HasRolesAndAbilities ;
class User extends Model
{
use HasRolesAndAbilities;
}
Crea una instancia de 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 );
Si está utilizando la inyección de dependencia en su aplicación, puede registrar la instancia Bouncer
como un singleton en el contenedor:
use Silber Bouncer Bouncer ;
use Illuminate Container Container ;
Container:: getInstance ()-> singleton (Bouncer::class, function () {
return Bouncer:: create ();
});
Ahora puedes inyectar Bouncer
en cualquier clase que lo necesite.
El método create
crea una instancia Bouncer
con valores predeterminados razonables. Para personalizarlo completamente, use el método make
para obtener una instancia de fábrica. Llame create()
en la fábrica para crear la instancia Bouncer
:
use Silber Bouncer Bouncer ;
$ bouncer = Bouncer:: make ()
-> withCache ( $ customCacheInstance )
-> create ();
Consulte la clase Factory
para ver todas las personalizaciones disponibles.
Establezca qué modelo se utiliza como modelo de usuario en toda su aplicación:
$ bouncer -> useUserModel (User::class);
Para configuración adicional, consulte la sección Configuración a continuación.
De forma predeterminada, las consultas de Bouncer se almacenan en caché para la solicitud actual. Para un mejor rendimiento, es posible que desee habilitar el almacenamiento en caché de solicitudes cruzadas.
Agregar roles y habilidades a los usuarios se hace extremadamente fácil. No es necesario crear un rol o una habilidad de antemano. Simplemente pase el nombre del rol/habilidad y Bouncer lo creará si no existe.
Nota: todos los ejemplos siguientes utilizan la fachada
Bouncer
. Si no usas fachadas, puedes inyectar una instancia deSilberBouncerBouncer
en tu clase.
Creemos un rol llamado admin
y démosle la capacidad de ban-users
de nuestro sitio:
Bouncer:: allow ( ' admin ' )-> to ( ' ban-users ' );
Eso es todo. Detrás de escena, Bouncer creará un modelo Role
y un modelo Ability
para usted.
Si desea agregar atributos adicionales al rol/habilidad, como un título legible por humanos, puede crearlos manualmente usando los métodos role
y ability
en la clase Bouncer
:
$ admin = Bouncer:: role ()-> firstOrCreate ([
' name ' => ' admin ' ,
' title ' => ' Administrator ' ,
]);
$ ban = Bouncer:: ability ()-> firstOrCreate ([
' name ' => ' ban-users ' ,
' title ' => ' Ban users ' ,
]);
Bouncer:: allow ( $ admin )-> to ( $ ban );
Para ahora otorgar la función admin
a un usuario, simplemente dígale al portero que al usuario en cuestión se le debe asignar la función de administrador:
Bouncer:: assign ( ' admin ' )-> to ( $ user );
Alternativamente, puede llamar al método assign
directamente en el usuario:
$ user -> assign ( ' admin ' );
A veces es posible que quieras darle a un usuario una habilidad directamente, sin usar un rol:
Bouncer:: allow ( $ user )-> to ( ' ban-users ' );
Aquí también puedes lograr lo mismo directamente desde el usuario:
$ user -> allow ( ' ban-users ' );
A veces es posible que desees restringir una capacidad a un tipo de modelo específico. Simplemente pase el nombre del modelo como segundo argumento:
Bouncer:: allow ( $ user )-> to ( ' edit ' , Post::class);
Si desea restringir la capacidad a una instancia de modelo específica, pase el modelo real en su lugar:
Bouncer:: allow ( $ user )-> to ( ' edit ' , $ post );
Utilice el método toOwn
para permitir a los usuarios administrar sus propios modelos:
Bouncer:: allow ( $ user )-> toOwn (Post::class);
Ahora, al verificar en la puerta si el usuario puede realizar una acción en una publicación determinada, el user_id
de usuario de la publicación se comparará con el id
del usuario que inició sesión (esto se puede personalizar). Si coinciden, la puerta permitirá la acción.
Lo anterior otorgará todas las habilidades en los modelos "propiedad" de un usuario. Puede restringir las capacidades siguiendo con una llamada al método 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 ' ]);
También puedes permitir que los usuarios posean todo tipo de modelos en tu aplicación:
Bouncer:: allow ( $ user )-> toOwnEverything ();
// And to restrict ownership to a given ability
Bouncer:: allow ( $ user )-> toOwnEverything ()-> to ( ' view ' );
El portero también puede retirar un rol previamente asignado a un usuario:
Bouncer:: retract ( ' admin ' )-> from ( $ user );
O hacerlo directamente sobre el usuario:
$ user -> retract ( ' admin ' );
El portero también puede eliminar una habilidad previamente otorgada a un usuario:
Bouncer:: disallow ( $ user )-> to ( ' ban-users ' );
O directamente en el usuario:
$ user -> disallow ( ' ban-users ' );
Nota: si el usuario tiene un rol que le permite
ban-users
, aún tendrá esa capacidad. Para no permitirlo, elimine la capacidad del rol o retire el rol del usuario.
Si la habilidad se ha otorgado a través de un rol, dígale al portero que elimine la habilidad del rol:
Bouncer:: disallow ( ' admin ' )-> to ( ' ban-users ' );
Para eliminar una habilidad para un tipo de modelo específico, pasa su nombre como segundo argumento:
Bouncer:: disallow ( $ user )-> to ( ' delete ' , Post::class);
Advertencia: si el usuario tiene la capacidad de
delete
una instancia$post
específica, el código anterior no eliminará esa capacidad. Tendrá que eliminar la capacidad por separado, pasando el$post
real como segundo argumento, como se muestra a continuación.
Para eliminar una habilidad para una instancia de modelo específica, pasa el modelo real en su lugar:
Bouncer:: disallow ( $ user )-> to ( ' delete ' , $ post );
Nota : el método
disallow
solo elimina las habilidades que se le otorgaron previamente a este usuario/rol. Si desea no permitir un subconjunto de lo que ha permitido una habilidad más general, utilice el métodoforbid
.
Bouncer también te permite forbid
una habilidad determinada, para un control más detallado. En ocasiones, es posible que desees otorgarle a un usuario/rol una habilidad que cubra una amplia gama de acciones, pero luego restringir un pequeño subconjunto de esas acciones.
A continuación se muestran algunos ejemplos:
Puede permitir que un usuario vea todos los documentos en general, pero tenga un documento específico altamente clasificado que no se le debería permitir ver:
Bouncer:: allow ( $ user )-> to ( ' view ' , Document::class);
Bouncer:: forbid ( $ user )-> to ( ' view ' , $ classifiedDocument );
Es posible que desee permitir que sus superadmin
hagan todo en su aplicación, incluso agregar o eliminar usuarios. Entonces es posible que tengas una función admin
que pueda hacer de todo además de administrar usuarios:
Bouncer:: allow ( ' superadmin ' )-> everything ();
Bouncer:: allow ( ' admin ' )-> everything ();
Bouncer:: forbid ( ' admin ' )-> toManage (User::class);
Es posible que desees prohibir ocasionalmente a los usuarios, quitándoles el permiso para todas las capacidades. Sin embargo, eliminar todos sus roles y habilidades significaría que cuando se elimine la prohibición tendremos que descubrir cuáles eran sus roles y habilidades originales.
Usar una habilidad prohibida significa que pueden mantener todos sus roles y habilidades existentes, pero aún así no estar autorizados para nada. Podemos lograr esto creando un rol banned
especial, para el cual prohibiremos todo:
Bouncer:: forbid ( ' banned ' )-> everything ();
Luego, cada vez que queramos prohibir a un usuario, le asignaremos el rol banned
:
Bouncer:: assign ( ' banned ' )-> to ( $ user );
Para eliminar la prohibición, simplemente le quitaremos el rol al usuario:
Bouncer:: retract ( ' banned ' )-> from ( $ user );
Como puedes ver, las habilidades prohibidas de Bouncer te brindan mucho control granular sobre los permisos de tu aplicación.
Para eliminar una habilidad prohibida, utiliza el método unforbid
:
Bouncer:: unforbid ( $ user )-> to ( ' view ' , $ classifiedDocument );
Nota : esto eliminará cualquier habilidad previamente prohibida. No permitirá automáticamente la habilidad si aún no está permitida por una habilidad regular diferente otorgada a este usuario/rol.
Nota : En términos generales, no debería ser necesario verificar los roles directamente. Es mejor permitirle a un rol ciertas habilidades y luego verificar esas habilidades. Si lo que necesitas es muy general, puedes crear habilidades muy amplias. Por ejemplo, una capacidad
access-dashboard
siempre es mejor que verificar directamente los rolesadmin
oeditor
. En el raro caso de que desee verificar una función, esa funcionalidad está disponible aquí.
El portero puede comprobar si un usuario tiene un rol específico:
Bouncer:: is ( $ user )-> a ( ' moderator ' );
Si el rol que estás comprobando comienza con una vocal, es posible que desees utilizar el método de an
:
Bouncer:: is ( $ user )-> an ( ' admin ' );
A la inversa, también puedes comprobar si un usuario no tiene un rol específico:
Bouncer:: is ( $ user )-> notA ( ' moderator ' );
Bouncer:: is ( $ user )-> notAn ( ' admin ' );
Puede comprobar si un usuario tiene uno de muchos roles:
Bouncer:: is ( $ user )-> a ( ' moderator ' , ' editor ' );
También puedes comprobar si el usuario tiene todos los roles indicados:
Bouncer:: is ( $ user )-> all ( ' editor ' , ' moderator ' );
También puedes comprobar si un usuario no tiene ninguno de los roles indicados:
Bouncer:: is ( $ user )-> notAn ( ' editor ' , ' moderator ' );
Estas comprobaciones también se pueden realizar directamente en el usuario:
$ user -> isAn ( ' admin ' );
$ user -> isA ( ' subscriber ' );
$ user -> isNotAn ( ' admin ' );
$ user -> isNotA ( ' subscriber ' );
$ user -> isAll ( ' editor ' , ' moderator ' );
Puede consultar a sus usuarios si tienen un rol determinado:
$ users = User:: whereIs ( ' admin ' )-> get ();
También puede pasar varios roles para consultar usuarios que tengan cualquiera de los roles dados:
$ users = User:: whereIs ( ' superadmin ' , ' admin ' )-> get ();
Para consultar usuarios que tienen todos los roles dados, use el método whereIsAll
:
$ users = User:: whereIsAll ( ' sales ' , ' marketing ' )-> get ();
Puede obtener todos los roles de un usuario directamente desde el modelo de usuario:
$ roles = $ user -> getRoles ();
Puede obtener todas las habilidades de un usuario directamente desde el modelo de usuario:
$ abilities = $ user -> getAbilities ();
Esto devolverá una colección de las habilidades permitidas del usuario, incluidas las habilidades otorgadas al usuario a través de sus roles.
También puedes obtener una lista de habilidades que han sido explícitamente prohibidas:
$ forbiddenAbilities = $ user -> getForbiddenAbilities ();
La autorización de usuarios se maneja directamente en Laravel's Gate
o en el modelo de usuario ( $user->can($ability)
).
Por conveniencia, la clase Bouncer
proporciona estos métodos de transferencia:
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 );
Estos llaman directamente a sus métodos equivalentes en la clase Gate
.
Bouncer no agrega sus propias directivas de cuchillas. Dado que Bouncer trabaja directamente con la puerta de Laravel, simplemente use su directiva @can
para verificar las habilidades del usuario actual:
@can ('update', $post)
< a href =" {{ route('post.update', $post) }} " > Edit Post </ a >
@endcan
Dado que generalmente no se recomienda verificar los roles directamente, Bouncer no se envía con una directiva separada para eso. Si aún insistes en verificar los roles, puedes hacerlo usando la directiva general @if
:
@ if ( $ user -> isAn ( ' admin ' ))
//
@endif
Todas las consultas ejecutadas por Bouncer se almacenan en caché para la solicitud actual. Si habilita el almacenamiento en caché entre solicitudes, el caché persistirá en diferentes solicitudes.
Siempre que lo necesites, puedes actualizar completamente el caché del Bouncer:
Bouncer:: refresh ();
Nota: la actualización completa del caché para todos los usuarios utiliza etiquetas de caché si están disponibles. No todos los controladores de caché admiten esto. Consulte la documentación de Laravel para ver si su controlador admite etiquetas de caché. Si su controlador no admite etiquetas de caché,
refresh
de llamadas puede ser un poco lenta, dependiendo de la cantidad de usuarios en su sistema.
Alternativamente, puedes actualizar el caché solo para un usuario específico:
Bouncer:: refreshFor ( $ user );
Nota : cuando se utilizan ámbitos de arrendamiento múltiple, esto solo actualizará la caché del usuario en el contexto del alcance actual. Para borrar los datos almacenados en caché para el mismo usuario en un contexto de alcance diferente, se debe llamar desde dentro de ese alcance.
Bouncer es totalmente compatible con aplicaciones multiinquilino, lo que le permite integrar perfectamente las funciones y capacidades de Bouncer para todos los inquilinos dentro de la misma aplicación.
Para comenzar, primero publique el middleware de alcance en su aplicación:
php artisan vendor:publish --tag="bouncer.middleware"
El middleware ahora se publicará en app/Http/Middleware/ScopeBouncer.php
. Este middleware es donde le dice a Bouncer qué inquilino usar para la solicitud actual. Por ejemplo, suponiendo que todos sus usuarios tengan un atributo account_id
, así es como se vería su middleware:
public function handle ( $ request , Closure $ next )
{
$ tenantId = $ request -> user ()-> account_id ;
Bouncer:: scope ()-> to ( $ tenantId );
return $ next ( $ request );
}
Por supuesto, usted es libre de modificar este middleware para adaptarlo a las necesidades de su aplicación, como extraer la información del inquilino de un subdominio, etc.
Ahora que el middleware está instalado, asegúrese de registrarlo en su kernel HTTP:
protected $ middlewareGroups = [
' web ' => [
// Keep the existing middleware here, and add this:
App Http Middleware ScopeBouncer::class,
]
];
Todas las consultas de Bouncer ahora se limitarán al inquilino determinado.
Dependiendo de la configuración de su aplicación, es posible que no desee que todas las consultas se limiten al inquilino actual. Por ejemplo, puede tener un conjunto fijo de roles/habilidades que son los mismos para todos los inquilinos y solo permitir que sus usuarios controlen a qué usuarios se les asignan qué roles y qué roles tienen qué habilidades. Para lograr esto, puede indicarle al alcance de Bouncer que solo alcance las relaciones entre los modelos de Bouncer, pero no los modelos en sí:
Bouncer:: scope ()-> to ( $ tenantId )-> onlyRelations ();
Además, es posible que su aplicación ni siquiera permita a sus usuarios controlar qué habilidades tiene un rol determinado. En ese caso, indique al alcance de Bouncer que excluya las capacidades de rol del alcance, de modo que esas relaciones permanezcan globales en todos los inquilinos:
Bouncer:: scope ()-> to ( $ tenantId )-> onlyRelations ()-> dontScopeRoleAbilities ();
Si sus necesidades son aún más especializadas que las descritas anteriormente, puede crear su propio Scope
con cualquier lógica personalizada que necesite:
use Silber Bouncer Contracts Scope ;
class MyScope implements Scope
{
// Whatever custom logic your app needs
}
Luego, en un proveedor de servicios, registre su alcance personalizado:
Bouncer:: scope ( new MyScope );
Bouncer llamará a los métodos en la interfaz Scope
en varios puntos de su ejecución. Eres libre de manejarlos según tus necesidades específicas.
Bouncer se envía con valores predeterminados razonables, por lo que la mayoría de las veces no debería ser necesaria ninguna configuración. Para un control más detallado, Bouncer se puede personalizar llamando a varios métodos de configuración en la clase Bouncer
.
Si solo usa una o dos de estas opciones de configuración, puede incluirlas en el método boot
principal de su AppServiceProvider
. Si comienzan a crecer, puede crear una clase BouncerServiceProvider
separada en su directorio app/Providers
(recuerde registrarla en la matriz de configuración providers
).
De forma predeterminada, todas las consultas ejecutadas por Bouncer se almacenan en caché para la solicitud actual. Para un mejor rendimiento, es posible que desee utilizar el almacenamiento en caché de solicitudes cruzadas:
Bouncer:: cache ();
Advertencia: si habilita el almacenamiento en caché de solicitudes cruzadas, usted es responsable de actualizar el caché cada vez que realice cambios en las funciones/habilidades del usuario. Para saber cómo actualizar el caché, lea Cómo actualizar el caché.
Por el contrario, es posible que en ocasiones desees desactivar completamente el caché, incluso dentro de la misma solicitud:
Bouncer:: dontCache ();
Esto es particularmente útil en pruebas unitarias, cuando desea ejecutar afirmaciones contra roles/habilidades que se acaban de otorgar.
Para cambiar los nombres de las tablas de la base de datos utilizados por Bouncer, pase una matriz asociativa al método tables
. Las claves deben ser los nombres de las tablas predeterminadas de Bouncer y los valores deben ser los nombres de las tablas que desea utilizar. No es necesario pasar todos los nombres de las tablas; sólo los que desea cambiar.
Bouncer:: tables ([
' abilities ' => ' my_abilities ' ,
' permissions ' => ' granted_abilities ' ,
]);
La migración publicada de Bouncer utiliza los nombres de las tablas de esta configuración, así que asegúrese de tenerlos en su lugar antes de ejecutar la migración.
Puede ampliar fácilmente los modelos Role
y Ability
integrados de 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
}
Alternativamente, puede usar los rasgos IsAbility
e IsRole
de Bouncer sin extender ninguno de los modelos de 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
}
Si usa los rasgos en lugar de extender los modelos de Bouncer, asegúrese de configurar usted mismo el nombre $table
y los campos $fillable
adecuados.
Independientemente del método que utilice, el siguiente paso es decirle a Bouncer que use sus modelos personalizados:
Bouncer:: useAbilityModel ( App Models Ability::class);
Bouncer:: useRoleModel ( App Models Role::class);
Nota : Eloquent determina la clave externa de las relaciones en función del nombre del modelo principal (consulte los documentos de Eloquent). Para simplificar las cosas, nombre sus clases personalizadas de la misma manera que las de Bouncer:
Ability
yRole
, respectivamente.Si necesita usar nombres diferentes, asegúrese de actualizar su archivo de migración o anular los métodos de relación para establecer explícitamente sus claves externas.
De forma predeterminada, Bouncer utiliza automáticamente el modelo de usuario del guardia de autenticación predeterminado.
Si estás usando Bouncer con una protección no predeterminada y usa un modelo de usuario diferente, debes informarle a Bouncer sobre el modelo de usuario que deseas usar:
Bouncer:: useUserModel ( App Admin::class);
En Bouncer, el concepto de propiedad se utiliza para permitir a los usuarios realizar acciones en modelos de los que "poseen".
De forma predeterminada, Bouncer comparará el user_id
del modelo con la clave principal del usuario actual. Si es necesario, se puede configurar con un atributo diferente:
Bouncer:: ownedVia ( ' userId ' );
Si diferentes modelos utilizan diferentes columnas para la propiedad, puedes registrarlos por separado:
Bouncer:: ownedVia (Post::class, ' created_by ' );
Bouncer:: ownedVia (Order::class, ' entered_by ' );
Para un mayor control, puede pasar un cierre con su lógica personalizada:
Bouncer:: ownedVia (Game::class, function ( $ game , $ user ) {
return $ game -> team_id == $ user -> team_id ;
});
Hay algunos conceptos en Bouncer sobre los que la gente sigue preguntando, así que aquí hay una breve lista de algunos de esos temas:
La siembra de los roles y habilidades iniciales se puede realizar en una clase de siembra normal de Laravel. Comience creando un archivo seeder específico para Bouncer:
php artisan make:seeder BouncerSeeder
Coloque todos sus códigos de roles y habilidades de siembra en el método run
del sembrador. A continuación se muestra un ejemplo de cómo podría verse:
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.
}
}
Para ejecutarlo realmente, pase el nombre de clase del sembrador a la opción class
del comando db:seed
:
php artisan db:seed --class=BouncerSeeder
scope
de Bouncer se puede utilizar para separar diferentes partes del sitio, creando un silo para cada una de ellas con su propio conjunto de roles y habilidades:
Cree un middleware ScopeBouncer
que tome un $identifier
y lo establezca como el alcance actual:
use Bouncer , Closure ;
class ScopeBouncer
{
public function handle ( $ request , Closure $ next , $ identifier )
{
Bouncer:: scope ()-> to ( $ identifier );
return $ next ( $ request );
}
}
Registre este nuevo middleware como middleware de ruta en su clase de kernel HTTP:
protected $ routeMiddleware = [
// Keep the other route middleware, and add this:
' scope-bouncer ' => App Http Middleware ScopeBouncer::class,
];
En su proveedor de servicios de ruta, aplique este middleware con un identificador diferente para las rutas públicas y las rutas del panel, respectivamente:
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 ' ));
Eso es todo. Todos los roles y habilidades ahora tendrán un alcance separado para cada sección de su sitio. Para ajustar el alcance del alcance, consulte Personalización del alcance de Bouncer.
A partir de Laravel 5.4, el juego de caracteres predeterminado de la base de datos ahora es utf8mb4
. Si está utilizando versiones anteriores de algunas bases de datos (MySQL inferior a 5.7.7 o MariaDB inferior a 10.2.2) con Laravel 5.4+, obtendrá un error de SQL al intentar crear un índice en una columna de cadena. Para solucionar este problema, cambie la longitud de cadena predeterminada de Laravel en su AppServiceProvider
:
use Illuminate Support Facades Schema ;
public function boot ()
{
Schema:: defaultStringLength ( 191 );
}
Puedes leer más en este artículo de Laravel News.
Las columnas JSON son una adición relativamente nueva a MySQL (5.7.8) y MariaDB (10.2.7). Si está utilizando una versión anterior de estas bases de datos, no puede utilizar columnas JSON.
La mejor solución sería actualizar su base de datos. Si eso no es posible actualmente, puede cambiar su archivo de migración publicado para usar una columna text
en su lugar:
- $table->json('options')->nullable();
+ $table->text('options')->nullable();
bouncer:clean
El comando bouncer:clean
elimina las habilidades no utilizadas. Al ejecutar este comando se eliminarán 2 tipos de habilidades no utilizadas:
Habilidades no asignadas : habilidades que no están asignadas a nadie. Por ejemplo:
Bouncer:: allow ( $ user )-> to ( ' view ' , Plan::class);
Bouncer:: disallow ( $ user )-> to ( ' view ' , Plan::class);
En este punto, la capacidad de "ver planes" no está asignada a nadie, por lo que se eliminará.
Nota : dependiendo del contexto de su aplicación, es posible que no desee eliminarlas. Si permite que sus usuarios administren habilidades en la interfaz de usuario de su aplicación, probablemente no desee eliminar habilidades no asignadas. Vea abajo.
Habilidades huérfanas : habilidades de modelos cuyos modelos han sido eliminados:
Bouncer:: allow ( $ user )-> to ( ' delete ' , $ plan );
$ plan -> delete ();
Dado que el plan ya no existe, la capacidad ya no sirve para nada, por lo que se eliminará.
Si solo desea eliminar un tipo de habilidad no utilizada, ejecútela con una de las siguientes opciones:
php artisan bouncer:clean --unassigned
php artisan bouncer:clean --orphaned
Si no le pasas ninguna bandera, eliminará ambos tipos de habilidades no utilizadas.
Para ejecutar automáticamente este comando periódicamente, agréguelo a la programación del kernel de su consola:
$ 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 );
Algunas de estas funciones también están disponibles directamente en el modelo de usuario:
$ 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 ();
Entre los millones de paquetes que Spatie tan amablemente ha otorgado a la comunidad, encontrará el excelente paquete laravel-permission. Al igual que Bouncer, se integra muy bien con las verificaciones de permisos y puertas integradas de Laravel, pero tiene un conjunto diferente de opciones de diseño en lo que respecta a sintaxis, estructura de base de datos y características.
Bouncer es un software de código abierto con licencia MIT