Есть куча пакетов для Laravel для управления ролями пользователей и разрешениями. Наиболее популярными из них являются роли и разрешения Spaties, а также роли и разрешения Laratrust. Мы можем легко управлять ролями и разрешениями в Laravel с помощью этих пакетов. Но в этом уроке наша цель состоит в том, чтобы создать систему ролей и разрешений без каких-либо пакетов. Поэтому мы не собираемся использовать какой-либо тип пакета для создания этой системы ролей и разрешений Laravel 10.
В этом уроке я создам полный Laravel 10 ролей и разрешений без пакета. Чтобы создать эти системы ролей и разрешений Laravel, нам нужно сначала понять сценарий ролей и разрешений для пользователя. Итак , что мы собираемся сделать в этом уроке, давайте посмотрим на сценарий:
- У пользователя может быть роль
- Роль может иметь множество разрешений
- У пользователей может быть несколько ролей
Так что это требование, которое мы собираемся реализовать. Мы также реализуем промежуточное ПО и пользовательскую директиву blade для обработки вошедших в систему пользователей в соответствии с их ролями и разрешениями.
Давайте посмотрим на изображение панели мониторинга предварительного просмотра этой роли и разрешений Laravel 10:Вошел в систему как роль пользователя:Шаг 1: Загрузите свежийLaravel На первом шаге Laravel 10 ролей и разрешений без пакета загрузите новое приложение Laravel
с помощью следующей команды:Шаг 2:
composer create-project laravel/laravel example-app
Создайте аутентификацию Нам нужна аутентификация.
Чтобы создать простую аутентификацию начальной загрузки, выполните следующую команду:Шаг 3: Подключение базы данных Теперьподключите базу данных
composer require laravel/ui --dev
php artisan ui bootstrap --auth
npm install
npm run dev
, потому что нам нужна миграция для этого Laravel роли и разрешения пример:.env
Шаг 4:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=password
Создание модели
Нам нужна модель для создания ролей и разрешений пользователей. Итак, давайте создадим нашу модель, используя приведенную ниже команду, чтобы выполнить роли и разрешения Laravel 10 без пакета.
php artisan make:model Permission -m
php artisan make:model Role -m
Теперь обновите файл миграции, например:Таблицы миграций для разрешений:
<?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');
}
};
<?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');
}
};
Теперь пришло время создать несколько сводных таблиц, Мы создадим новый файл миграции для таблицы . Итак, выполните приведенную ниже команду, чтобы создать
<?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');
}
};
Теперь давайте создадим сводную таблицуusers_permissions
для .
<?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
В рамках определенной роли пользователь может иметь определенные разрешения. Например, у пользователя может быть разрешение на публикацию темы, а у администратора может быть разрешение на редактирование или удаление темы. В этом случае давайте настроим новую таблицу для roles_permissions, чтобы справиться с этой сложностью.
php artisan make:migration create_roles_permissions_table --create=roles_permissions
Теперь обновите like:Теперь выполните следующую команду, чтобы создать миграцию
<?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');
}
};
Шаг 5: Обновитемодель с помощью отношений Теперь обновите ролевую модель с помощью такой связи:app\Models\Role.php Теперь обновите roles_permissions
модель разрешений с помощью
php artisan migrate
такой связи:
Шаг 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');
}
}
Создайте характеристику службы
Теперь на этом шаге мы создадим функцию службы или вспомогательной черты, чтобы легко обрабатывать роли и разрешения в приложении 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();
}
}
Теперь обновите модель User с помощью этой черты.
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',
];
}
Шаг 7. Создание директивы
Role BladeТеперь на этот раз мы создадим директиву @role()
blade. Поэтому обновите поставщика службы приложений следующим образом:Шаг 8:
Шаг 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; ?>";
});
}
}
Создайте сеялку
Теперь на этом шаге мы создадим некоторые фиктивные данные для создания ролей и разрешений для пользователей. Итак, выполните приведенную ниже команду:Теперь обновите его следующим образом:База данных\Seeders\RoleSeeder.php Теперь обновите сеялку базы данных следующим образом:
php artisan make:seeder RoleSeeder
<?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);
}
}
DatabaseSeeder\DatabaseSeeder.php
<?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);
}
}
Теперь выполните приведенную ниже команду, чтобы сгенерировать поддельные данные для тестирования наших ролей и разрешений laravel 10 без приложения пакета.
php artisan db:seed
Шаг 9: Создайте промежуточное программное обеспечение
На этом шаге мы создадим промежуточное программное обеспечение роли, чтобы мы могли обрабатывать запросы пользователей с помощью промежуточного программного обеспечения.
php artisan make:middleware RoleMiddleware
И обновите его следующим образом:App\Http\Middleware\RoleMiddleware.php Теперь зарегистрируйте его внутри kernel.php
вот так:
<?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);
}
}
<?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,
];
}
Теперь все готово. Мы можем проверить запросы пользователей и роли следующим образом:
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
Проверьте роли и разрешения пользователей в контроллере:Используйте в своем маршруте следующим образом:
<?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');
}
}
}
Использование в групповом маршруте:Читайте также:
<?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 Отправить SMS Учебное пособие
Заключение
Посмотрите на это, мы реализовали все требования, связанные с ролями и разрешениями. Надеюсь, теперь в любых приложениях Laravel мы сможем реализовать эти laravel 10 ролей и разрешений без пакета. Надеюсь, этот учебник по ролям и разрешениям laravel поможет вам.