To integrate an admin area within a multi-tenancy project, you can follow a more structured and secure approach by separating the concerns of tenant-specific data and global admin functionalities. Here’s a solution that leverages Laravel's middleware, guards, and route groups to achieve this:
Step 1: Define Middleware for Tenant and Admin
Create middleware to differentiate between tenant and admin access. You can use Laravel's artisan command to create middleware:
php artisan make:middleware TenantMiddleware
php artisan make:middleware AdminMiddleware
In TenantMiddleware, you can check if the user belongs to a tenant:
// app/Http/Middleware/TenantMiddleware.php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class TenantMiddleware
{
public function handle($request, Closure $next)
{
if (Auth::check() && Auth::user()->is_tenant) {
return $next($request);
}
return redirect('/login');
}
}
In AdminMiddleware, you can check if the user is an admin:
// app/Http/Middleware/AdminMiddleware.php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class AdminMiddleware
{
public function handle($request, Closure $next)
{
if (Auth::check() && Auth::user()->is_admin) {
return $next($request);
}
return redirect('/login');
}
}
Step 2: Register Middleware
Register the middleware in app/Http/Kernel.php:
protected $routeMiddleware = [
// ...
'tenant' => \App\Http\Middleware\TenantMiddleware::class,
'admin' => \App\Http\Middleware\AdminMiddleware::class,
];
Step 3: Define Routes for Tenant and Admin
Use route groups to separate tenant and admin routes:
// routes/web.php
// Tenant routes
Route::middleware(['auth', 'tenant'])->group(function () {
Route::get('/tenant/dashboard', [TenantController::class, 'dashboard'])->name('tenant.dashboard');
// Add more tenant-specific routes here
});
// Admin routes
Route::middleware(['auth', 'admin'])->group(function () {
Route::get('/admin/dashboard', [AdminController::class, 'dashboard'])->name('admin.dashboard');
// Add more admin-specific routes here
});
Step 4: Create Guards for Tenant and Admin (Optional)
If you need more control over authentication, you can create custom guards in config/auth.php:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'tenant' => [
'driver' => 'session',
'provider' => 'tenants',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
'tenants' => [
'driver' => 'eloquent',
'model' => App\Models\Tenant::class,
],
],
Step 5: Implement Controllers
Create controllers for tenant and admin functionalities:
php artisan make:controller TenantController
php artisan make:controller AdminController
In TenantController:
// app/Http/Controllers/TenantController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TenantController extends Controller
{
public function dashboard()
{
return view('tenant.dashboard');
}
}
In AdminController:
// app/Http/Controllers/AdminController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AdminController extends Controller
{
public function dashboard()
{
return view('admin.dashboard');
}
}
Step 6: Create Views
Create views for tenant and admin dashboards:
-
resources/views/tenant/dashboard.blade.php -
resources/views/admin/dashboard.blade.php
Conclusion
By using middleware, route groups, and optionally custom guards, you can securely and efficiently manage both tenant-specific data and global admin functionalities within the same project. This approach keeps the concerns separated and ensures that only authorized users can access the respective areas.