Laravel多重身份验证导航栏

时间:2018-09-07 10:06:16

标签: php laravel

在我的应用程序中,我使用多个保护措施以及单独的usersadmins表来设置多重身份验证。

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'token',
        'provider' => 'users',
    ],

    'admin' => [
        'driver' => 'session',
        'provider' => 'admins',
    ],
],

此外,管理员用户可以具有完全或部分管理员权限。

这是因为全部和部分管理员只能查看候选应用程序,他们不能创建新管理员或管理职位列表

为了实现分离,我希望建立一个名为Role的自定义中间件,位于此处:

app \ 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>

这是一种肮脏的做事方式吗,有什么方法可以改善这种结构,这样我就不必在很多身份验证检查中包装导航项了?

1 个答案:

答案 0 :(得分:0)

最佳方式使用中间件

public function handle($request, Closure $next) {

    if (Sentinel::check() && Sentinel::getUser()->roles()->first()->slug == 'user') {
        return $next($request);
    } elseif (Sentinel::check() && Sentinel::getUser()->roles()->first()->slug == 'admin') {
        return redirect('admin-dashboard');
    } else {
        return redirect('login');
    }

}

在您的route / web.php文件中 用一张简单的支票

Route::group(['middleware'=>'user'], function()
{

  //Write you route here
}