В моем приложении я настроил multi-auth с использованием нескольких охранников, а также отдельной таблицы users
и admins
.
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
],
Кроме того, пользователи с правами администратора могут иметь уровень доступа администратора, полный или частичный.
Это потому, что полные и частичные администраторы могут только просматривать приложения-кандидаты, они не могут создавать новых администраторов или управлять списками вакансий
Чтобы добиться разделения, я хочу, чтобы я настроил промежуточное ПО под названием Role, которое находится здесь:
приложение \ Http \ Middleware \ Role.php
Код для которого следующий
<?php
namespace App\Http\Middleware;
use Closure;
use Auth;
class Role
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next, ...$roles)
{
if (Auth::guard('admin')->user()) {
$user = Auth::guard('admin')->user();
if ($user->is_admin) {
return $next($request);
} else {
if ($user->hasAnyRole($roles)) {
return $next($request);
} else {
return response('You do not have sufficient priveledges to perform this action.', 403);
}
}
}
}
}
В дополнение к этому я также настроил пользовательские директивы Blade
Blade::if('user', function () {
return Auth::guard('web')->check();
});
Blade::if('admin', function () {
return Auth::guard('admin')->check() && Auth::guard('admin')->user()->is_admin;
});
Blade::if('full', function () {
return Auth::guard('admin')->check() && Auth::guard('admin')->user()->is_full;
});
Blade::if('partial', function () {
return Auth::guard('admin')->check() && Auth::guard('admin')->user()->is_partial;
});
Атрибуты в каждой проверке роли администратора определяются в моей модели администратора следующим образом:
/**
* Check whether this admin has full admin status
*
* @return void
*/
public function getIsAdminAttribute()
{
return $this->access_level == 'admin' ? true : false;
}
/**
* Check whether this user has Partial status
*
* @return void
*/
public function getIsFullAttribute()
{
return $this->access_level == 'full' ? true : false;
}
/**
* Check whether this user has Partial status
*
* @return void
*/
public function getIsPartialAttribute()
{
return $this->access_level == 'partial' ? true : false;
}
/**
* Check whether this admin has a particular role
*
* @param [type] $role
* @return void
*/
public function hasRole($role)
{
if ($this->access_level == $role) {
return true;
}
return false;
}
/**
* Check whether this admin user has a role within a list of roles
*
* @param [type] $roles
* @return boolean
*/
public function hasAnyRole($roles)
{
if (is_array($roles)) {
foreach ($roles as $role) {
if ($this->hasRole($role)) {
return true;
}
}
} else {
if ($this->hasRole($roles)) {
return true;
}
}
return false;
}
Наконец, вот где я застрял: у меня есть одна панель навигации для всех пользователей, но я хотел отображать только гостевые маршруты для пользователей, которые не вошли в систему, но вы можете войти как администратор и как пользователь в то же время.
Учитывая это, я хотел отображать элементы навигации, только если вы гость и не вошли в систему как администратор.
Код ниже.
<nav class="navbar navbar-expand-md " id="generic">
<div class="container">
<a class="navbar-brand" href="/">
<img src="https://www.newable.co.uk/assets/img/common/newable-logo-blue.svg" width="auto" height="45" alt="">
</a>
<div class="navbar-toggler-right">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar" aria-controls="navbarTogglerDemo02"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
</div>
<div class="collapse navbar-collapse flex-column " id="navbar">
<ul class="navbar-nav w-100 justify-content-end ">
{{-- Admin navigation section --}}
@auth('admin')
<li class="nav-item">
<a class="nav-link" href="{{route('admins.dashboard')}}">Dashboard</a>
</li>
@admin
<li class="nav-item">
<a class="nav-link" href="{{route('vacancies.create')}}">Post vacancy</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{route('vacancies.index')}}">Manage vacancies</a>
</li>
@endadmin
<li class="nav-item">
<a class="nav-link" href="{{route('applications.index')}}">View applications</a>
</li>
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
@csrf
</form>
<li class="nav-item">
<a class="nav-link" href="{{ route('logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">
{{ __('Logout') }}
</a>
</li>
@endauth
{{-- User navigation section --}}
@user
<li class="nav-item">
<a class="nav-link" href="{{route('user-dashboard')}}">Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{route('application-form')}}">Job Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{route('user-job-applications')}}">Your Applications</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{route('user-account-settings')}}">Settings</a>
</li>
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
@csrf
</form>
<li class="nav-item">
<a class="nav-link" href="{{ route('logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">
{{ __('Logout') }}
</a>
</li>
@enduser
@guest
@if(!Auth::guard('admin')->check())
<li class="nav-item">
<a class="nav-link" href="{{route('login')}}">Login</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{route('register')}}">Register</a>
</li>
@endif
@endguest
</ul>
</div>
</div>
</nav>
Это грязный способ ведения дел, есть ли способ, которым я могу улучшить эту структуру, чтобы мне не нужно было оборачивать элементы навигации во многих проверках аутентификации?