Bouncer integrates seamlessly with Laravel's middleware system and leverages Laravel's native authorization features, particularly the Gate, to provide a powerful and flexible way to manage roles and abilities through middleware. The integration is smooth due to Bouncer's design, which aligns well with Laravel's architecture and middleware pipeline.
Overview of Bouncer and Middleware Integration
Bouncer is a package designed for managing roles and abilities in Laravel applications using Eloquent models. It allows dynamic handling of permissions with an expressive and fluent API, creating roles and assigning abilities either directly to users or through roles. This flexibility makes it an excellent fit for Laravel's middleware system, where access control checks can be centrally enforced during request processing.
Bouncer works by hooking into Laravel's authorization gate functionality. When Laravel's built-in authorization gate checks are invokedâfor example, using the `can` middleware or the `@can` Blade directiveâBouncer automatically consults its roles and abilities to determine if the user has the required permission to proceed. This means Bouncer effectively extends Laravel's native authorization system without requiring significant changes to the application or middleware stack.
Using Bouncer with Laravel's Middleware System
Middleware in Laravel is used to filter HTTP requests entering an application. It can inspect, modify, or reject requests before they reach controllers. Bouncer integrates with this by enabling middleware to perform authorization checks based on roles and abilities defined in Bouncer.
1. Authorization Middleware (`can`)
Laravel comes with built-in `can` middleware that checks if an authenticated user has a given ability. Since Bouncer integrates with Laravel's Gate, it can be used seamlessly with this middleware. For example, protecting a route with Bouncer's abilities is as simple as adding the following middleware to a route:
php
Route::get('/posts/{post}/edit', 'PostController@edit')->middleware('can:update,post');
Here, Bouncer will be queried automatically when the `can:update,post` middleware is run. It checks whether the authenticated user has the "update" ability on the given `post` model, either through direct abilities or assigned roles.
2. Creating Custom Middleware for Scoping
Bouncer supports multi-tenancy and scoped roles/abilities. Laravel's middleware system can register custom middleware that sets the current Bouncer scope for a request. This is useful when roles and abilities should be tenant-specific or context-dependent. For example, a middleware named `ScopeBouncer` can be introduced:
php
namespace App\Http\Middleware;
use Closure;
use Bouncer;
class ScopeBouncer
{
public function handle($request, Closure $next, $scopeIdentifier)
{
Bouncer::scope()->to($scopeIdentifier);
return $next($request);
}
}
This middleware is then registered in the HTTP kernel and applied to routes to ensure Bouncer checks are limited to a specific tenant or context within the application.
3. Middleware Registration and Usage
After publishing and creating the middleware, it should be registered in the HTTP kernel under either the `$middlewareGroups` or `$routeMiddleware` array:
php
protected $routeMiddleware = [
'scope-bouncer' => \App\Http\Middleware\ScopeBouncer::class,
// other middlewares...
];
Developers can then apply middleware globally or to specific routes and route groups, allowing granular control of authorization scopes in middleware.
Middleware Benefits with Bouncer Integration
- Centralized Access Control: Middleware acts as a gatekeeper. Integrating Bouncer means all authorization logic can be centralizedâmiddleware enforces permissions on routes before requests hit controllers.
- Dynamic Permission Checks: Bouncer's dynamic role and ability management allows for permissions to be added, updated, or removed at runtime without changing code, and middleware will respect those changes immediately.
- Multi-tenancy Support: Middleware can dynamically set Bouncer scopes per request, enabling handling of multiple tenants with distinct roles and abilities using the same Laravel app instance.
- Flexibility with Laravel Features: Bouncer works with Laravel's policies, gates, and Blade directives (`@can`). Authorization middleware that relies on these features inherently supports Bouncer's roles and permissions.
- Direct and Role-based Abilities: Middleware authorization checks can verify abilities given directly to users or inherited via roles managed by Bouncer, allowing fine-grained control without complicated checks in controllers.
How Bouncer Authorization Checks Operate in Middleware Context
When middleware like `can` is used, Laravel triggers Gate checks. Bouncer registers these checks automatically upon use, hooking into authorization events. If a user has the required abilityâeither assigned explicitly or through a roleâBouncer authorizes the request; otherwise, middleware rejects it with HTTP 403 Forbidden or redirects users to login if unauthenticated.
For example, a typical middleware-based authorization workflow with Bouncer looks like this:
- A request arrives at a protected route with `can:update,post` middleware.
- Laravel's middleware invokes the authorization gate check for the current user.
- Bouncer intercepts the gate check and queries the database for the user's direct abilities and roles.
- If authorized, the middleware passes the request to the controller.
- If not, the middleware aborts the request.
This integration ensures that Bouncer fully participates in Laravel's authorization pipeline without requiring additional middleware or special manual checks in controllers.
Practical Implementation Steps
1. Install Bouncer
Using composer: `composer require silber/bouncer`
Add Bouncer's trait (`HasRolesAndAbilities`) to the User model.
Publish and run the migrations for roles and abilities tables.
2. Create and Assign Roles and Abilities
Use Bouncer's fluent API to create roles and abilities dynamically. Roles can be assigned to users, and abilities can be assigned to roles or users directly.
3. Apply Middleware
Use Laravel's built-in `can` middleware to guard routes based on Bouncer's abilities.
Optionally, create custom middleware for scoping or multi-tenancy as needed.
4. Check Abilities in Views and Controllers
Use Laravel's `@can` Blade directive and `$user->can()` method to integrate UI and controller logic with Bouncer permissions.
Enhanced Middleware Use Cases
- Sectioned Role Management: Use scoped middleware to separate public vs. admin dashboard roles and permissions.
- Dynamic Tenant Permissions: Middleware can dynamically load the tenant context, ensuring Bouncer applies tenant-specific roles.
- Fallback Rules: Middleware can combine hard-coded rules with Bouncer's dynamic permissions to create flexible authorization scenarios.
Summary of Key Middleware Integration Features with Bouncer
- Bouncer is designed to be framework-agnostic but has excellent first-class integration with Laravel middleware through Laravel's Gate.
- It supports direct ability grants and role-based permissions that middleware can check transparently.
- Middleware can set contextual scopes for multi-tenant apps, enabling complex applications to keep roles isolated.
- Laravel's native authorization middleware can be used unchanged, with Bouncer augmenting the backend authorization logic seamlessly.
- The integration supports dynamic, runtime updates to permissions that immediately reflect in middleware-based authorization checks.