Laravel后台管理系统-Filament(权限管理)
环境
- Php8.2
- Mysql8.0
第一步:创建 Laravel 12 项目
- 使用
composer安装示例项目 example-1
- 配置数据库
.env
......
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_example_1
DB_USERNAME=root
DB_PASSWORD=123456
......
- 迁移数据库
- 运行项目
第二步 安装Filament
- 基础安装
- 创建
admin_users表 并创建守卫admin
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('admin_users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('admin_users');
}
};
更改auth.php
......
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admin_users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => env('AUTH_MODEL', App\Models\User::class),
],
'admin_users' => [
'driver' => 'eloquent',
'model' => env('ADMIN_AUTH_MODEL', App\Models\AdminUser::class),
],
],
......
为filament添加守卫admin
App\Providers\Filament\AdminPanelProvider.php
<?php
namespace App\Providers\Filament;
use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\AuthenticateSession;
use Filament\Http\Middleware\DisableBladeIconComponents;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Pages;
use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Colors\Color;
use Filament\Widgets;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
class AdminPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->default()
->id('admin')
->path('admin')
->login()
->authGuard('admin')
->colors([
'primary' => Color::Amber,
])
->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources')
->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages')
->pages([
Pages\Dashboard::class,
])
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
->widgets([
Widgets\AccountWidget::class,
Widgets\FilamentInfoWidget::class,
])
->middleware([
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
])
->authMiddleware([
Authenticate::class,
]);
}
}
更改App\Models\AdminUser.php
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class AdminUser extends Authenticatable
{
/** @use HasFactory<\Database\Factories\UserFactory> */
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var list<string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var list<string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
}
- 创建user
第三步 安装并配置filament-shield
- 安装
-
配置
# config/filament-shield.php
<?php
return [
...
// 定义认证服务Model,改为上一章创建的AdminUser
'auth_provider_model' => [
'fqcn' => 'App\\Models\\AdminUser',
],
...
];
- 为AdminUser模型添加HasRoles Trait
use Spatie\Permission\Traits\HasRoles;
class AdminUser extends Authenticatable implements FilamentUser
{
use HasRoles;
}
设置Shield
发布翻译
-
自定义策略
# app/Policies/AdminUserPolicy.php
# 不需要的权限可以自行删除
<?php
namespace App\Policies;
use App\Models\AdminUser;
use Illuminate\Auth\Access\HandlesAuthorization;
class AdminUserPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view any models.
*/
public function viewAny(AdminUser $adminUser): bool
{
return $adminUser->canAny('view_admin::user');
}
/**
* Determine whether the user can view the model.
*/
public function view(AdminUser $adminUser): bool
{
return $adminUser->can('view_admin::user');
}
/**
* Determine whether the user can create models.
*/
public function create(AdminUser $adminUser): bool
{
return $adminUser->can('create_admin::user');
}
/**
* Determine whether the user can update the model.
*/
public function update(AdminUser $adminUser): bool
{
return $adminUser->can('update_admin::user');
}
/**
* Determine whether the user can delete the model.
*/
public function delete(AdminUser $adminUser): bool
{
return $adminUser->can('delete_admin::user');
}
/**
* Determine whether the user can restore the model.
*/
public function restore(AdminUser $adminUser): bool
{
return $adminUser->can('restore_admin::user');
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(AdminUser $adminUser): bool
{
return $adminUser->can('force_delete_admin::user');
}
}
# app/Filament/Resources/AdminUserResource.php
<?php
namespace App\Filament\Resources;
use App\Filament\Resources\AdminUserResource\Pages;
use App\Models\AdminUser;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Support\Facades\Auth;
class AdminUserResource extends Resource
{
protected static ?string $model = AdminUser::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = '权限管理';
protected static ?string $navigationLabel = '用户管理';
protected static ?string $modelLabel = '用户';
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')
->label('用户名')
->required()
->maxLength(255),
Forms\Components\TextInput::make('email')
->label('邮箱')
->email()
->required()
->maxLength(255),
Forms\Components\TextInput::make('password')
->label('密码')
->password()
->required()
->maxLength(255),
Forms\Components\Select::make('role')
->relationship('roles', 'name')
->label('角色')
->required(),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name')
->label('用户名')
->searchable(),
Tables\Columns\TextColumn::make('email')
->label('邮箱')
->searchable(),
Tables\Columns\TextColumn::make('created_at')
->label('创建时间')
->dateTime(),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListAdminUsers::route('/'),
'create' => Pages\CreateAdminUser::route('/create'),
'edit' => Pages\EditAdminUser::route('/{record}/edit'),
];
}
}
第四步 创建角色与用户
角色:超级管理员 root 普通管理员 user1 只读管理员 user2
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('catename');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('categories');
}
};
<?php
namespace App\Policies;
use App\Models\AdminUser;
use Illuminate\Auth\Access\HandlesAuthorization;
class CategoryPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view any models (影响 Filament 菜单是否显示).
*/
public function viewAny(AdminUser $user): bool
{
return $user->can('view_category');
}
/**
* Determine whether the user can view the model.
*/
public function view(AdminUser $user): bool
{
return $user->can('view_category');
}
/**
* Determine whether the user can create models.
*/
public function create(AdminUser $user): bool
{
return $user->can('create_category');
}
/**
* Determine whether the user can update the model.
*/
public function update(AdminUser $user): bool
{
return $user->can('update_category');
}
/**
* Determine whether the user can delete the model.
*/
public function delete(AdminUser $user): bool
{
return $user->can('delete_category');
}
public function deleteAny(AdminUser $user): bool
{
return $user->can('delete_any_category');
}
/**
* Determine whether the user can restore the model.
*/
public function restore(AdminUser $user): bool
{
return $user->can('restore_category');
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(AdminUser $user): bool
{
return $user->can('force_delete_category');
}
}