4.6 KiB
4.6 KiB
c77_rbac Usage Guide - Part 3: Framework Integration
This is Part 3 of the comprehensive c77_rbac usage guide, covering detailed integration with popular web frameworks.
Complete Guide Structure:
- Part 1: Core Concepts and Basic Usage
- Part 2: Advanced Usage Scenarios
- Part 3: Framework Integration (this document)
- Part 4: Real-World Examples and Performance Optimization
- Part 5: Security Best Practices and Troubleshooting
Table of Contents
Laravel Integration
Complete Laravel Setup
1. Service Provider
<?php
// app/Providers/RbacServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;
use App\Services\RbacService;
class RbacServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(RbacService::class);
}
public function boot()
{
// Register middleware
$this->app['router']->aliasMiddleware('rbac.context',
\App\Http\Middleware\SetRbacContext::class);
$this->app['router']->aliasMiddleware('rbac.require',
\App\Http\Middleware\RequirePermission::class);
// Integrate with Laravel Gates
Gate::before(function ($user, $ability) {
// Check RBAC format: 'feature:scope_type/scope_id'
if (strpos($ability, ':') !== false) {
[$feature, $scope] = explode(':', $ability, 2);
if (strpos($scope, '/') !== false) {
[$scopeType, $scopeId] = explode('/', $scope, 2);
return app(RbacService::class)->can($feature, $scopeType, $scopeId);
}
}
// Default to global scope
return app(RbacService::class)->can($ability, 'global', 'all');
});
// Register Artisan commands
if ($this->app->runningInConsole()) {
$this->commands([
\App\Console\Commands\RbacAssignRole::class,
\App\Console\Commands\RbacSyncAdmin::class,
\App\Console\Commands\RbacListPermissions::class,
]);
}
}
}
2. RBAC Service
<?php
// app/Services/RbacService.php
namespace App\Services;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
class RbacService
{
/**
* Check if current user has access to a feature
*/
public function can(string $feature, string $scopeType = 'global', string $scopeId = 'all'): bool
{
if (!Auth::check()) {
return false;
}
$userId = Auth::id();
$cacheKey = "rbac:can:{$userId}:{$feature}:{$scopeType}:{$scopeId}";
return Cache::remember($cacheKey, 300, function () use ($feature, $userId, $scopeType, $scopeId) {
try {
$result = DB::selectOne(
'SELECT public.c77_rbac_can_access(?, ?, ?, ?) AS allowed',
[$feature, (string)$userId, $scopeType, $scopeId]
);
return $result->allowed ?? false;
} catch (\Exception $e) {
Log::error('RBAC permission check failed', [
'feature' => $feature,
'user_id' => $userId,
'scope_type' => $scopeType,
'scope_id' => $scopeId,
'error' => $e->getMessage()
]);
return false;
}
});
}
/**
* Assign role to user
*/
public function assignRole(int $userId, string $role, string $scopeType = 'global', string $scopeId = 'all'): bool
{
try {
DB::statement(
'SELECT public.c77_rbac_assign_subject(?, ?, ?, ?)',
[(string)$userId, $role, $scopeType, $scopeId]
);
// Clear user's permission cache
$this->clearUserCache($userId);
Log::info('Role assigned', [
'user_id' => $userId,
'role' => $role,
'scope_type' => $scopeType,
'scope_id' => $scopeId
]);
return true;
} catch (\Exception $e) {
Log::error('Failed to assign role', [
'user_id' => $userId,
'role' => $role,