【问题标题】:Laravel multi-auth navigation barLaravel 多认证导航栏
【发布时间】:2019-02-12 16:06:00
【问题描述】:

在我的应用程序中,我使用多个保护设置了多重身份验证,以及一个单独的 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::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;
        });

每个管理员角色检查中的属性在我的 Admin 模型中定义如下:

/**
 * 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>

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

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    使用中间件的最佳方式

    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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-14
      • 2020-07-25
      • 1970-01-01
      • 1970-01-01
      • 2011-07-27
      • 2018-01-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多