Laravel 10.x karkasas. Naudotojų rolės
Laravel karkasas neturi naudotojų rolių, todėl jas reikia pasidaryti pačiam. Įvairūs programuotojai siūlo nemažai sprendimų, tačiau šiuo metu vienas populiariausių būdų tai padaryti yra naudoti Spatie Laravel Permision paketą. Paketo įdiegimui naudokite komandą:
Naudojant Spatie Laravel Permision paketą rolės gali būti priskirtos įvairiems modeliams, tačiau mes naudosim tik
Visos penkios lentelės automatiškai yra susiejamos ryšiais, tačiau jos nėra susiejamos su

Dabar atsidarykite modelį
Failo
Atsidarykite failą
Atsidarykite failą
Nuo šiol galite priskirti naudotojams įvairias roles. Tačiau dar liko nesutvarkyti maršrutai, todėl bet kuris naudotojas gali patekti į bet kurį puslapį. Pereikite prie sekančio skyriaus Maršrutai, kad sužinoti kaip tai atlikti.
Daugiau apie naudotojų roles skaitykite oficialioje Spatie Laravel Permission dokumentacijoje.
Taip pat rekomenduoju peržiūrėti šias video pamokas, kad sužinotumėte daugiau Spatie Laravel Permission paketo galimybių:
Spatie Laravel Permission Package Tutorial | Introduction #1
Spatie Laravel Permission Package Tutorial | User Role and Permission #2
Spatie Laravel Permission Package Tutorial | Explaining user role and permission together #3
Spatie Laravel Permission Package Tutorial | Using Middleware for permission and role #4
Spatie Laravel Permission Package Tutorial | User Role and Permission #5
composer require spatie/laravel-permission
Įsidiegus paketą reikia sugeneruoti migracijos ir konfigūracijos failus, tam įvykdykite komandą:
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
Įvykdžius šią komandą kataloge ../library/databse/migrations/
atsiras failas *_create_permission_tables.php
, o kataloge ../library/config/
- failas permission.php
. Šiame konfigūracijos faile galima nustatyti įvairius paketo parametrus.Naudojant Spatie Laravel Permision paketą rolės gali būti priskirtos įvairiems modeliams, tačiau mes naudosim tik
User
modelį, todėl atsidarykite ../library/config/permission.php
failą ir eilutes:
'model_has_permissions' => 'model_has_permissions',
...
'model_has_roles' => 'model_has_roles',
...
'model_morph_key' => 'model_id',
pakeiskite į:
'model_has_permissions' => 'user_has_permissions',
...
'model_has_roles' => 'user_has_roles',
...
'model_morph_key' => 'user_id',
Įvykdykite lentelių migraciją į duomenų bazę:
php artisan migrate
Įvykdžius lentelių migraciją duomenų bazėje atsiras penkios naujos lentelės: roles
, permissions
, user_has_roles
, user_has_permissions
ir role_has_permissions
. Naudosime tik dvi iš jų: roles
ir user_has_roles
.Visos penkios lentelės automatiškai yra susiejamos ryšiais, tačiau jos nėra susiejamos su
users
lentele, todėl sukurkime migraciją set_permission_foreign
:
php artisan make:migration set_permission_foreign
Šios migracijos metode up()
įrašykite:
Schema::table('user_has_roles', function (Blueprint $table) {
$table->foreign('user_id')->references('id')->on('users');
});
Schema::table('user_has_permissions', function (Blueprint $table) {
$table->foreign('user_id')->references('id')->on('users');
});
Tada įvykdykite šią migraciją:
php artisan migrate
Nustačius ryšius duomenų bazės struktūra turėtų atrodyti taip:
Dabar atsidarykite modelį
User
ir prie naudojamų klasių įrašykite:
use Spatie\Permission\Traits\HasRoles;
Taip pat klasės viduje po eilute use TwoFactorAuthenticatable;
įrašykite eilutę:
use HasRoles;
Sukurkite du naujus valdiklius Users
ir Roles
:
php artisan make:controller Admin/UsersController --resource
php artisan make:controller Admin/RolesController --resource
Valdiklio UsersController
failo struktūra:
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Spatie\Permission\Models\Role;
class UsersController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$users = User::all();
return view('admin.users.index', compact('users'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$roles = Role::pluck('name', 'id');
$roles->prepend('---Please select---', 0);
$roles->all();
return view('admin.users.form', compact('roles'));
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$user = User::create($request->all());
$user->assignRole($request->roles);
return redirect('admin/users')->with('success', 'User added successfully.');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$user = User::findOrFail($id);
return view('admin.users.show', compact('user'));
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$user = User::findOrFail($id);
$roles = Role::pluck('name', 'id');
$roles->prepend('---Please select---', 0);
$roles->all();
$selected_roles[] = array();
foreach ($user->roles as $role) {
$selected_roles[] = $role->id;
}
return view('admin.users.form', compact('user', 'roles', 'selected_roles'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$user = User::findOrFail($id);
$user->update($request->all());
$user->syncRoles($request->roles);
return redirect('admin/users')->with('success', 'User updated successfully.');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$user = User::findOrFail($id);
$user->delete();
return redirect('admin/users')->with('success', 'User deleted successfully.');
}
}
Valdiklio RolesController
failo struktūra:
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Spatie\Permission\Models\Role;
class RolesController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$roles = Role::all();
return view('admin.roles.index', compact('roles'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return view('admin.roles.form');
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
Role::create($request->all());
return redirect('admin/roles')->with('success', 'Role added successfully.');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$role = Role::findOrFail($id);
return view('admin.roles.show', compact('role'));
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$role = Role::findOrFail($id);
return view('admin.roles.form', compact('role'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$role = Role::findOrFail($id);
$role->update($request->all());
return redirect('admin/roles')->with('success', 'Role updated successfully.');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$role = Role::findOrFail($id);
$role->delete();
return redirect('admin/roles')->with('success', 'Role deleted successfully.');
}
}
Dabar sukurkime vaizdus naudotojams ir rolėms. Iš pradžių kataloge ../library/resources/views/admin/
sukurkite katalogus users
ir roles
, o juose failus index.blade.php
, show.blade.php
ir form.blade.php
.Failo
../users/index.blade.php
struktūra:
@extends('layouts.admin')
@section('title', 'Users')
@section('content')
<div class="card">
<div class="card-header">
<a href="{{ url('admin/users/create') }}" class="btn btn-primary"><i class="fas fa-plus"></i> Add user</a>
</div>
<div class="card-body">
@if(Session::has('success'))
<div class="alert alert-success alert-dismissible fade show" role="alert">
{{ Session::get('success') }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
@php
Session::forget('success');
@endphp
</div>
@endif
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>E-mail</th>
<th>Role</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach($users as $user)
<tr>
<td>{{ $user->id }}</td>
<td>{{ $user->name }}</td>
<td><a href="mailto:{{ $user->email }}">{{ $user->email }}</a></td>
<td>@foreach($user->roles as $role) {{ $role->name }} @endforeach</td>
<td>
<a href="{{ url('admin/users/'.$user->id.'/edit') }}" class="btn btn-primary btn-sm"><i class="fas fa-edit"></i> Edit</a>
<a href="{{ url('admin/users/'.$user->id) }}" class="btn btn-success btn-sm"><i class="fas fa-eye"></i> View</a>
{!! Form::open(['method'=>'DELETE', 'url' => ['admin/users', $user->id], 'style' => 'display:inline']) !!}
{!! Form::button('<i class="fas fa-trash-alt"></i> Delete', ['class' => 'btn btn-danger btn-sm', 'type' => 'submit']) !!}
{!! Form::close() !!}
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
@endsection
Failo ../users/show.blade.php
struktūra:
@extends('layouts.admin')
@section('title', 'Users')
@section('content')
<div class="card">
<div class="card-header">
<a href="{{ url('/admin/users/'.$user->id.'/edit') }}" class="btn btn-primary"><i class="fas fa-edit"></i> Edit user</a>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered">
<tbody>
<tr>
<td>ID</td>
<td>{{ $user->id }}</td>
</tr>
<tr>
<td>Name</td>
<td>{{ $user->name }}</td>
</tr>
<tr>
<td>E-mail</td>
<td><a href="mailto:{{ $user->email }}">{{ $user->email }}</a></td>
</tr>
<tr>
<td>Role</td>
<td>@foreach($user->roles as $role) {{ $role->name }} @endforeach</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
@endsection
Failo ../users/form.blade.php
struktūra:
@extends('layouts.admin')
@section('title', 'Users')
@section('content')
<div class="card">
<div class="card-header">
<h6 class="m-0 font-weight-bold text-primary">
@if(isset($user))
Edit exist user
@else
Create new user
@endif
</h6>
</div>
<div class="card-body">
@if(isset($user))
{!! Form::model($user, ['url' => ['admin/users', $user->id], 'method' => 'patch', 'class' => 'needs-validation']) !!}
@else
{!! Form::open(['url' => 'admin/users', 'class' => 'needs-validation']) !!}
@endif
<div class="form-group">
{!! Form::label('name', 'Name: ', ['class' => 'col-sm-3']) !!}
<div class="col-sm-6">
{!! Form::text('name', null, ['class' => 'form-control'.($errors->has('name') ? ' is-invalid' : ''), 'required' => 'required']) !!}
{!! $errors->first('name', '<div class="invalid-feedback">:message</div>') !!}
</div>
</div>
<div class="form-group">
{!! Form::label('email', 'E-mail: ', ['class' => 'col-sm-3']) !!}
<div class="col-sm-6">
{!! Form::email('email', null, ['class' => 'form-control'.($errors->has('email') ? ' is-invalid' : ''), 'required' => 'required']) !!}
{!! $errors->first('email', '<div class="invalid-feedback">:message</div>') !!}
</div>
</div>
@if(!isset($user))
<div class="form-group">
{!! Form::label('password', 'Password: ', ['class' => 'col-sm-3']) !!}
<div class="col-sm-6">
{!! Form::password('password', ['class' => 'form-control'.($errors->has('password') ? ' is-invalid' : ''), 'required' => 'required']) !!}
{!! $errors->first('password', '<div class="invalid-feedback">:message</div>') !!}
</div>
</div>
<div class="form-group">
{!! Form::label('password_confirmation', 'Confirm password: ', ['class' => 'col-sm-3']) !!}
<div class="col-sm-6">
{!! Form::password('password_confirmation', ['class' => 'form-control'.($errors->has('password_confirmation') ? ' is-invalid' : ''), 'required' => 'required']) !!}
{!! $errors->first('password_confirmation', '<div class="invalid-feedback">:message</div>') !!}
</div>
</div>
@endif
<div class="form-group">
{!! Form::label('role_id', 'Role: ', ['class' => 'col-sm-3']) !!}
<div class="col-sm-6">
{!!Form::select('role_id', $roles, isset($user) ? $selected_roles : null, ['class' => 'form-control', 'multiple' => 'multiple', 'name' => 'roles[]', 'required' => 'required'])!!}
{!! $errors->first('role_id', '<div class="invalid-feedback">:message</div>') !!}
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-3">
{!! Form::submit('Save', ['class' => 'btn btn-primary form-control']) !!}
</div>
</div>
{!! Form::close() !!}
</div>
</div>
@endsection
Failo ../roles/index.blade.php
struktūra:
@extends('layouts.admin')
@section('title', 'Roles')
@section('content')
<div class="card">
<div class="card-header">
<a href="{{ url('admin/roles/create') }}" class="btn btn-primary"><i class="fas fa-plus"></i> Add role</a>
</div>
<div class="card-body">
@if(Session::has('success'))
<div class="alert alert-success alert-dismissible fade show" role="alert">
{{ Session::get('success') }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
@php
Session::forget('success');
@endphp
</div>
@endif
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>ID</th>
<th>Role</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach($roles as $role)
<tr>
<td>{{ $role->id }}</td>
<td>{{ $role->name }}</td>
<td>
<a href="{{ url('admin/roles/'.$role->id.'/edit') }}" class="btn btn-primary btn-sm"><i class="fas fa-edit"></i> Edit</a>
<a href="{{ url('admin/roles/'.$role->id) }}" class="btn btn-success btn-sm"><i class="fas fa-eye"></i> View</a>
{!! Form::open(['method'=>'DELETE', 'url' => ['admin/roles', $role->id], 'style' => 'display:inline']) !!}
{!! Form::button('<i class="fas fa-trash-alt"></i> Delete', ['class' => 'btn btn-danger btn-sm', 'type' => 'submit']) !!}
{!! Form::close() !!}
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
@endsection
Failo ../roles/show.blade.php
struktūra:
@extends('layouts.admin')
@section('title', 'Role')
@section('content')
<div class="card">
<div class="card-header">
<a href="{{ url('/admin/roles/'.$role->id.'/edit') }}" class="btn btn-primary"><i class="fas fa-edit"></i> Edit role</a>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered">
<tbody>
<tr>
<td>ID</td>
<td>{{ $role->id }}</td>
</tr>
<tr>
<td>Role</td>
<td>{{ $role->name }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
@endsection
Failo ../roles/form.blade.php
struktūra:
@extends('layouts.admin')
@section('title', 'Roles')
@section('content')
<div class="card">
<div class="card-header">
<h6 class="m-0 font-weight-bold text-primary">
@if(isset($role))
Edit exist role
@else
Create new role
@endif
</h6>
</div>
<div class="card-body">
@if(isset($role))
{!! Form::model($role, ['url' => ['admin/roles', $role->id], 'method' => 'patch', 'class' => 'needs-validation']) !!}
@else
{!! Form::open(['url' => 'admin/roles', 'class' => 'needs-validation']) !!}
@endif
<div class="form-group">
{!! Form::label('name', 'Name: ', ['class' => 'col-sm-3']) !!}
<div class="col-sm-6">
{!! Form::text('name', null, ['class' => 'form-control'.($errors->has('name') ? ' is-invalid' : ''), 'required' => 'required']) !!}
{!! $errors->first('name', '<div class="invalid-feedback">:message</div>') !!}
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-3">
{!! Form::submit('Save', ['class' => 'btn btn-primary form-control']) !!}
</div>
</div>
{!! Form::close() !!}
</div>
</div>
@endsection
Atsidarykite maršrutų failą ir virš eilutės Auth::routes();
įterpkite šiuos maršrutus:
Route::get('/admin/users', [App\Http\Controllers\Admin\UsersController::class, 'index']);
Route::get('/admin/users/create', [App\Http\Controllers\Admin\UsersController::class, 'create']);
Route::post('/admin/users', [App\Http\Controllers\Admin\UsersController::class, 'store']);
Route::get('/admin/users/{id}', [App\Http\Controllers\Admin\UsersController::class, 'show']);
Route::get('/admin/users/{id}/edit', [App\Http\Controllers\Admin\UsersController::class, 'edit']);
Route::patch('/admin/users/{id}', [App\Http\Controllers\Admin\UsersController::class, 'update']);
Route::delete('/admin/users/{id}', [App\Http\Controllers\Admin\UsersController::class, 'destroy']);
Route::get('/admin/roles', [App\Http\Controllers\Admin\RolesController::class, 'index']);
Route::get('/admin/roles/create', [App\Http\Controllers\Admin\RolesController::class, 'create']);
Route::post('/admin/roles', [App\Http\Controllers\Admin\RolesController::class, 'store']);
Route::get('/admin/roles/{id}', [App\Http\Controllers\Admin\RolesController::class, 'show']);
Route::get('/admin/roles/{id}/edit', [App\Http\Controllers\Admin\RolesController::class, 'edit']);
Route::patch('/admin/roles/{id}', [App\Http\Controllers\Admin\RolesController::class, 'update']);
Route::delete('/admin/roles/{id}', [App\Http\Controllers\Admin\RolesController::class, 'destroy']);
Atsidarykite nuorodą http://localhost:8000/admin/roles ir sukurkite roles admin
, librarian
ir member
.Atsidarykite failą
../library/app/Actions/Fortify/CreateNewUser.php
, suraskite metodą create()
ir jame esantį kodą
return $user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
pakeiskite į
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
return $user->assignRole('member');
Paskutinė eilutė automatiškai kiekvienam naujai užregistruotam naudotojui pridės rolę member
.Atsidarykite failą
../library/resources/views/layouts/admin.blade.php
ir navigacijoje pridėkite porą nuorodų:
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
...
@role('admin')
<li class="nav-item">
<a href="{{ url('/admin/users') }}" class="nav-link">
<i class="nav-icon fas fa-user"></i>
<p>Users</p>
</a>
</li>
<li class="nav-item">
<a href="{{ url('/admin/roles') }}" class="nav-link">
<i class="nav-icon fas fa-key"></i>
<p>Roles</p>
</a>
</li>
@endrole
</ul>
Administravimo panelėje atsiras du nauji meniu punktai: Users
ir Roles
, kuriuos matys tik naudotojas, priskirtas admin
rolei.Nuo šiol galite priskirti naudotojams įvairias roles. Tačiau dar liko nesutvarkyti maršrutai, todėl bet kuris naudotojas gali patekti į bet kurį puslapį. Pereikite prie sekančio skyriaus Maršrutai, kad sužinoti kaip tai atlikti.
Daugiau apie naudotojų roles skaitykite oficialioje Spatie Laravel Permission dokumentacijoje.
Taip pat rekomenduoju peržiūrėti šias video pamokas, kad sužinotumėte daugiau Spatie Laravel Permission paketo galimybių:
Spatie Laravel Permission Package Tutorial | Introduction #1
Spatie Laravel Permission Package Tutorial | User Role and Permission #2
Spatie Laravel Permission Package Tutorial | Explaining user role and permission together #3
Spatie Laravel Permission Package Tutorial | Using Middleware for permission and role #4
Spatie Laravel Permission Package Tutorial | User Role and Permission #5