douhao8456 2018-09-07 10:06
浏览 336

Laravel多功能导航栏

In my application, I have set up multi-auth using multiple guards, as well as a separate users and admins table.

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

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

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

Further to this, admin users can have an access level of admin, full or partial.

This is because full and partial admins can only view candidate applications, they cannot create new admins, or manage job listings

In order to achieve the separation I desire I have set up a custom Middleware called Role, which is located here:

app\Http\Middleware\Role.php

The code for which is as follows

<?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);
                }
            }
        }
    }
}

To compliment this I have also set up custom Blade Directives

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;
        });

The attributes in each admin role check are defined in my Admin model as follows:

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

Finally, and here's where I get stuck: I have one navigation bar for all users, but I only wanted to display guest routes to users who aren't logged in, but you can be logged in as an admin and a user at the same time.

Given this, I only wanted to display navigation items if you're a guest and not logged in as an admin.

Code below.

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

Is this a dirty way of doing things, is there a way I can improve this structure so I don't have to wrap navigation items in so many authentication checks?

  • 写回答

1条回答 默认 最新

  • dsa88886666 2018-09-07 10:26
    关注

    Best way use Middleware

    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');
        }
    
    }
    

    In your route/web.php file use one simple check

    Route::group(['middleware'=>'user'], function()
    {
    
      //Write you route here
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题