Istnieje kilka pakietów dla Laravel do zarządzania rolami użytkowników i uprawnieniami. Role i uprawnienia Spaties oraz role i uprawnienia Laratrust są najpopularniejszymi z nich. Możemy łatwo zarządzać rolami i uprawnieniami w Laravel za pomocą tych pakietów. Ale w tym samouczku naszym celem jest utworzenie systemu ról i uprawnień bez żadnych pakietów. Więc nie będziemy używać żadnego rodzaju pakietu do tworzenia tego systemu ról i uprawnień Laravel 10.
W tym samouczku stworzę kompletny Laravel 10 ról i uprawnień bez pakietu. Aby utworzyć te role Laravel i systemy uprawnień, musimy najpierw zrozumieć scenariusz ról i uprawnień dla użytkownika. Więc co zrobimy w tym samouczku, zobaczmy scenariusz:
- Użytkownik może mieć rolę
- Rola może mieć wiele uprawnień
- Użytkownicy mogą mieć wiele ról
To jest wymóg, który zamierzamy wdrożyć. Implementujemy również dyrektywę oprogramowania pośredniczącego i niestandardową dyrektywę kasetową do obsługi zalogowanych użytkowników zgodnie z ich rolami i uprawnieniami.
Zobaczmy obraz podglądu pulpitu nawigacyjnego tej roli i uprawnień Laravel 10 samouczek:Zalogowany jako rola użytkownika:Krok 1: Pobierz świeży Laravel W pierwszym kroku ról i uprawnień Laravel
10 bez pakietu, pobierz nową aplikację Laravel, wykonując następujące polecenie:Krok 2:
composer create-project laravel/laravel example-app
Utwórz uwierzytelnianie
Potrzebujemy uwierzytelniania. Aby utworzyć proste uwierzytelnianie bootstrap za pomocą następującego polecenia:Krok 3: Połącz bazę danych Teraz podłącz bazę danych
composer require laravel/ui --dev
php artisan ui bootstrap --auth
npm install
npm run dev
, ponieważ potrzebujemy migracji dla tego Laravel role i uprawnienia przykład:.env
Krok 4:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=password
Utwórz model
Potrzebujemy modelu, aby nadać użytkownikom role i uprawnienia. Stwórzmy więc nasz model za pomocą poniższego polecenia, aby ukończyć Laravel 10 ról i uprawnień bez pakietu.
php artisan make:model Permission -m
php artisan make:model Role -m
Teraz zaktualizuj plik migracji, taki jak: Migracje dla tabeli uprawnień:
<?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('roles', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('roles');
}
};
Teraz czas utworzyć wiele tabel przestawnych, utworzymy nowy plik migracji dla tabeli users_permissions
. Uruchom poniższe polecenie,
<?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('permissions', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('permissions');
}
};
aby utworzyć
<?php
use App\Models\Permission;
use App\Models\User;
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('users_permissions', function (Blueprint $table) {
$table->foreignIdFor(User::class)->constrained()->cascadeOnDelete();
$table->foreignIdFor(Permission::class)->constrained()->cascadeOnDelete();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('users_permissions');
}
};
Teraz utwórzmy tabelę przestawną dla .
<?php
use App\Models\Role;
use App\Models\User;
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('users_roles', function (Blueprint $table) {
$table->foreignIdFor(User::class)->constrained()->cascadeOnDelete();
$table->foreignIdFor(Role::class)->constrained()->cascadeOnDelete();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('users_roles');
}
};
users_roles
W ramach określonej roli użytkownik może mieć określone uprawnienia. Na przykład użytkownik może mieć uprawnienia do publikowania tematu, a administrator może mieć uprawnienia do edytowania lub usuwania tematu. W takim przypadku skonfigurujmy nową tabelę dla roles_permissions, aby poradzić sobie z tą złożonością.
php artisan make:migration create_roles_permissions_table --create=roles_permissions
Teraz zaktualizuj podobne:Teraz uruchom następujące polecenie, aby utworzyć migrację
<?php
use App\Models\Permission;
use App\Models\Role;
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('roles_permissions', function (Blueprint $table) {
$table->foreignIdFor(Role::class)->constrained()->cascadeOnDelete();
$table->foreignIdFor(Permission::class)->constrained()->cascadeOnDelete();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('roles_permissions');
}
};
Krok5: Aktualizuj model z relacją
php artisan migrate
Teraz zaktualizuj model roli za pomocą relacji takiej jak ta: app\Models\Role.php Teraz zaktualizuj
roles_permissions
model uprawnień za pomocą relacji takiej jak ta:
Krok 6:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
use HasFactory;
public function permissions()
{
return $this->belongsToMany(Permission::class, 'roles_permissions');
}
public function users()
{
return $this->belongsToMany(User::class, 'users_roles');
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Permission extends Model
{
use HasFactory;
public function roles()
{
return $this->belongsToMany(Role::class, 'roles_permissions');
}
public function users()
{
return $this->belongsToMany(User::class, 'users_permissions');
}
}
Utwórz cechę usługi
Teraz w tym kroku utworzymy usługę lub cechę pomocniczą, aby łatwo obsługiwać role i uprawnienia w aplikacji Laravel 10.
App\Traits\HasPermissionsTrait.php
<?php
namespace App\Traits;
use App\Models\Role;
use App\Models\Permission;
trait HasPermissionsTrait
{
public function givePermissionsTo(...$permissions)
{
$permissions = $this->getAllPermissions($permissions);
if ($permissions === null) {
return $this;
}
$this->permissions()->saveMany($permissions);
return $this;
}
public function withdrawPermissionsTo(...$permissions)
{
$permissions = $this->getAllPermissions($permissions);
$this->permissions()->detach($permissions);
return $this;
}
public function refreshPermissions(...$permissions)
{
$this->permissions()->detach();
return $this->givePermissionsTo($permissions);
}
public function hasPermissionTo($permission)
{
return $this->hasPermissionThroughRole($permission) || $this->hasPermission($permission);
}
public function hasPermissionThroughRole($permission)
{
foreach($permission->roles as $role) {
if ($this->roles->contains($role)) {
return true;
}
}
return false;
}
public function hasRole(...$roles)
{
foreach($roles as $role) {
if ($this->roles->contains('name', $role)) {
return true;
}
}
return false;
}
public function roles()
{
return $this->belongsToMany(Role::class, 'users_roles');
}
public function permissions()
{
return $this->belongsToMany(Permission::class, 'users_permissions');
}
protected function hasPermission($permission)
{
return (bool) $this->permissions->where('name', $permission->name)->count();
}
protected function getAllPermissions(array $permissions)
{
return Permission::whereIn('name', $permissions)->get();
}
}
Teraz zaktualizuj model użytkownika przy użyciu tej cechy.
app\Models\User.php
<?php
namespace App\Models;
use App\Traits\HasPermissionsTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens,
HasFactory,
Notifiable,
HasPermissionsTrait;
protected $fillable = [
'name',
'email',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
Krok 7: Utwórz dyrektywę
Role BladeTym razem stworzymy dyrektywę ostrzową@role()
. Zaktualizuj dostawcę usług aplikacji w następujący sposób: Krok 8:
Krok 8:
<?php
namespace App\Providers;
use App\Models\Permission;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
}
public function boot(): void
{
try {
Permission::get()->map(function ($permission) {
Gate::define($permission->name, function ($user) use ($permission) {
return $user->hasPermissionTo($permission);
});
});
} catch (\Exception $e) {
report($e);
}
Blade::directive('role', function ($role) {
return "<?php if(auth()->check() && auth()->user()->hasRole({$role})) : ?>";
});
Blade::directive('endrole', function ($role) {
return "<?php endif; ?>";
});
}
}
Utwórz siewcę
Teraz w tym kroku utworzymy pewne dane pozorne, aby utworzyć role i uprawnienia z użytkownikami. Uruchom więc poniższe polecenie:Teraz zaktualizuj go w następujący sposób: Baza danych \ Seeders \ RoleSeeder.php Teraz zaktualizuj seeder bazy danych w następujący sposób:
php artisan make:seeder RoleSeeder
DatabaseSeeder \ DatabaseSeeder.php
<?php
namespace Database\Seeders;
use App\Models\Role;
use App\Models\User;
use App\Models\Permission;
use Illuminate\Database\Seeder;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
class RoleSeeder extends Seeder
{
public function run(): void
{
$permission = new Permission();
$permission->name = 'create-post';
$permission->save();
$role = new Role();
$role->name = 'admin';
$role->save();
$role->permissions()->attach($permission);
$permission->roles()->attach($role);
$permission = new Permission();
$permission->name = 'create-user';
$permission->save();
$role = new Role();
$role->name = 'user';
$role->save();
$role->permissions()->attach($permission);
$permission->roles()->attach($role);
$admin = Role::where('name', 'admin')->first();
$userRole = Role::where('name', 'user')->first();
$create_post = Permission::where('name', 'create-post')->first();
$create_user = Permission::where('name', 'create-user')->first();
$admin = new User();
$admin->name = 'Admin';
$admin->email = '[email protected]';
$admin->password = bcrypt('admin');
$admin->save();
$admin->roles()->attach($admin);
$admin->permissions()->attach($create_post);
$user = new User();
$user->name = 'User';
$user->email = '[email protected]';
$user->password = bcrypt('user');
$user->save();
$user->roles()->attach($userRole);
$user->permissions()->attach($create_user);
}
}
Teraz uruchom poniższe polecenie,
<?php
namespace Database\Seeders;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run(): void
{
$this->call(RoleSeeder::class);
}
}
aby wygenerować fałszywe dane, aby przetestować nasze role i uprawnienia laravel 10 bez aplikacji pakietu.
php artisan db:seed
Krok 9: Utwórz oprogramowanie
pośrednicząceW tym kroku utworzymy oprogramowanie pośredniczące roli, abyśmy mogli obsługiwać żądania użytkowników przy użyciu oprogramowania pośredniczącego.
php artisan make:middleware RoleMiddleware
I zaktualizuj go w następujący sposób: App \ HTTP \ Middleware \ RoleMiddleware.php Teraz zarejestruj go w kernel.php
następujący sposób:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class RoleMiddleware
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(
Request $request,
Closure $next,
$role,
$permission = null
): Response {
if (!$request->user()->hasRole($role)) {
abort(404);
}
if ($permission !== null && !$request->user()->can($permission)) {
abort(404);
}
return $next($request);
}
}
App \ HTTP \ Kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array<int, class-string|string>
*/
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* @var array<string, array<int, class-string|string>>
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
* The application's middleware aliases.
*
* Aliases may be used instead of class names to conveniently assign middleware to routes and groups.
*
* @var array<string, class-string|string>
*/
protected $middlewareAliases = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'role' => \App\Http\Middleware\RoleMiddleware::class,
];
}
Teraz wszystko jest gotowe. Możemy sprawdzić żądania użytkowników i role w następujący sposób:
resources/views/home.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Dashboard') }}</div>
<div class="card-body">
@if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
@endif
@role('admin')
{{ __('You are admin') }}
@endrole
@role('user')
{{ __('You are user') }}
@endrole
</div>
</div>
</div>
</div>
</div>
@endsection
Sprawdź role i uprawnienia użytkowników w kontrolerze:Użyj na trasie w następujący sposób:trasy/sieć Web.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TutorialController extends Controller
{
public function __invoke()
{
if (auth()->user()->can('create-user')) {
return view('welcome');
}
}
}
Użyj w trasie grupowej:Czytaj także:
<?php
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TutorialController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/
Route::get('/', TutorialController::class)->middleware('role:admin');
Route::group(['middleware' => 'role:admin'], function() {
//
});
Route::group(['middleware' => 'role:user'], function() {
//
});
Laravel 10 Twilio Wyślij SMS Samouczek
Wniosek
Spójrz na to, wdrożyliśmy wszystkie wymagania związane z rolami i uprawnieniami. Mam nadzieję, że teraz w każdej aplikacji Laravel, jesteśmy w stanie wdrożyć te role i uprawnienia laravel 10 bez pakietu. Mam nadzieję, że ten samouczek ról i uprawnień laravel ci pomoże.