본문 바로가기
iaa.dev/Laravel8

Laravel 8 관리자 화면 - 관리자 및 회원관리

by chopper.kid 2022. 1. 8.

이전까지의 관리화면 만드는 부분에 이어서 이번에는 관리자 / 회원 리스트 표시및 권한에 따라 화면을 표시할지 말지를 결정할 Policy 에 대해 설명합니다..

이미 많은 role , permission 등을 다루는 패키지들이 나와있고 spatie 의 여러 패키지들도 괜찮습니다만 , 

이곳에서 앞으로 다룰 글들에서는 되도록이면 laravel 이 가지고 있는 기능들을 사용하여 설명해나갈 예정입니다.

 

일단 아래 링크까지 한 상태에서 이어서 작업을 합니다.

 

 

Laravel 8 관리자 화면 (Multiple Authentication) - Admin 모델 사용

준비작업 이전글에서 작업한 상태까지 설치되어있으면 됩니다. Laravel 8 로그인/회원가입(Authentication) - Jetstream Laravel 로 웹애플리케이션을 만들때 가장 기본인 유저 로그인 / 가입 등의 기능은 이

vuxy.tistory.com

 

1.관리자화면 사이드 바 메뉴 정리

config/adminlte.php 의 'menu' 키의 값을 다 주석처리하고 다음과 같이 바꿉니다.

    'menu' => [
        // Navbar items:
        [
            'type'         => 'navbar-search',
            'text'         => 'search',
            'topnav_right' => true,
        ],
        [
            'type'         => 'fullscreen-widget',
            'topnav_right' => true,
        ],

        // Sidebar items:
        [
            'type' => 'sidebar-menu-search',
            'text' => 'search',
        ],
        // [
        //     'text' => 'blog',
        //     'url'  => 'admin/blog',
        //     'can'  => 'manage-blog',
        // ],
        [
            'text' => 'Users',
            'url'  => 'admin/users',
            'icon' => 'fas fa-fw fa-user',
        ],
        [
            'text' => 'Admin',
            'url'  => 'admin/admins',
            'icon' => 'fas fa-fw fa-user',
        ],

2.컨트롤러 작성

app/Http/Controllers/Admin/ 에 리소스컨트롤러 AdminController.php 와

 

<?php

namespace App\Http\Controllers\Admin;

use App\Models\Admin;
use App\Http\Requests\StoreAdminRequest;
use App\Http\Requests\UpdateAdminRequest;

class AdminController extends Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->authorizeResource(Admin::class, 'admin');
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $models = Admin::paginate();
        \Debugbar::info($models);

        return view(
            "admin.admins.index" ,
            [
                'models' => $models,
            ]
        );
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \App\Http\Requests\StoreAdminRequest  $request
     * @return \Illuminate\Http\Response
     */
    public function store(StoreAdminRequest $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Admin  $admin
     * @return \Illuminate\Http\Response
     */
    public function show(Admin $admin)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Admin  $admin
     * @return \Illuminate\Http\Response
     */
    public function edit(Admin $admin)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \App\Http\Requests\UpdateAdminRequest  $request
     * @param  \App\Models\Admin  $admin
     * @return \Illuminate\Http\Response
     */
    public function update(UpdateAdminRequest $request, Admin $admin)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Admin  $admin
     * @return \Illuminate\Http\Response
     */
    public function destroy(Admin $admin)
    {
        //
    }
}

 

UserController.php 를 작성

<?php

namespace App\Http\Controllers\Admin;

use App\Models\User;
use App\Http\Requests\StoreUserRequest;
use App\Http\Requests\UpdateUserRequest;

class UserController extends Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->authorizeResource(User::class, 'user');
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $models = User::paginate();
        \Debugbar::info($models);

        return view(
            "admin.users.index" ,
            [
                'models' => $models,
            ]
        );
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \App\Http\Requests\StoreUserRequest  $request
     * @return \Illuminate\Http\Response
     */
    public function store(StoreUserRequest $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\User  $user
     * @return \Illuminate\Http\Response
     */
    public function show(User $user)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\User  $user
     * @return \Illuminate\Http\Response
     */
    public function edit(User $user)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \App\Http\Requests\UpdateUserRequest  $request
     * @param  \App\Models\User  $user
     * @return \Illuminate\Http\Response
     */
    public function update(UpdateUserRequest $request, User $user)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\User $user
     * @return \Illuminate\Http\Response
     */
    public function destroy(User $user)
    {
        //
    }
}

3.뷰작성

resources/views/admins 와 resources/views/users 에 각각 index.blade.php 를 작성

@extends('adminlte::page')

@section('title', 'Dashboard')

@section('content_header')
    <h1>Dashboard</h1>
@stop

@section('content')
<div class="alert alert-success" role="alert">
    Welcome to admin users
    </div>

    <table class="table">
        <thead>
          <tr>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
        </tr>
        </thead>
        <tbody>
            @foreach ($models as $model)
          <tr>
            <td>{{ $model->id }}</td>
            <td>{{ $model->name }}<br>{{ $model->email }}</td>

            <td>{{ $model->created_at }}<br>
                {{ $model->updated_at }}</td>

        </tr>
          @endforeach
        </tbody>
      </table>
@stop

@section('css')
    <link rel="stylesheet" href="/css/admin_custom.css">
@stop

@section('js')
    <script> console.log('Hi!'); </script>
@stop
@extends('adminlte::page')

@section('title', 'Dashboard')

@section('content_header')
    <h1>Dashboard</h1>
@stop

@section('content')
<div class="alert alert-success" role="alert">
    Welcome to admin users
    </div>

    <table class="table">
        <thead>
          <tr>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
        </tr>
        </thead>
        <tbody>
            @foreach ($models as $model)
          <tr>
            <td>{{ $model->id }}</td>
            <td>{{ $model->name }}<br>{{ $model->email }}</td>

            <td>{{ $model->created_at }}<br>
                {{ $model->updated_at }}</td>

        </tr>
          @endforeach
        </tbody>
      </table>
@stop

@section('css')
    <link rel="stylesheet" href="/css/admin_custom.css">
@stop

@section('js')
    <script> console.log('Hi!'); </script>
@stop

4.Policy 작성

app/Policies 에 AdminPolicy.php 와 UserPolicy.php 를 작성후

<?php

namespace App\Policies;

//use App\Models\Admin;
use App\Models\UserInterface;
use Illuminate\Auth\Access\HandlesAuthorization;

class AdminPolicy
{
    use HandlesAuthorization;

    /**
     * Determine whether the user can view any models.
     *
     * @param  \App\Models\UserInterface  $user
     * @return \Illuminate\Auth\Access\Response|bool
     */
    public function viewAny(UserInterface $user)
    {
        if ($user->isAccessibleAdmins()) {
            return true;
        }
    }

    /**
     * Determine whether the user can view the model.
     *
     * @param  \App\Models\UserInterface  $user
     * @param  \App\Models\Admin  $createdAdmin
     * @return \Illuminate\Auth\Access\Response|bool
     */
    public function view(UserInterface $user, Admin $createdAdmin)
    {
        // //
        // return $admin->id === $createdAdmin->user_id
        //             ? Response::allow()
        //             : Response::deny('You do not own this post.');
    }

    /**
     * Determine whether the user can create models.
     *
     * @param  \App\Models\UserInterface  $user
     * @return \Illuminate\Auth\Access\Response|bool
     */
    public function create(UserInterface  $user)
    {
        //
    }

    /**
     * Determine whether the user can update the model.
     *
     * @param  \App\Models\UserInterface  $user
     * @param  \App\Models\Admin  $admin
     * @return \Illuminate\Auth\Access\Response|bool
     */
    public function update(UserInterface  $user, Admin $createdAdmin)
    {
        //
    }

    /**
     * Determine whether the user can delete the model.
     *
     * @param  \App\Models\UserInterface  $user
     * @param  \App\Models\Admin  $admin
     * @return \Illuminate\Auth\Access\Response|bool
     */
    public function delete(UserInterface  $user, Admin $createdAdmin)
    {
        //
    }

    /**
     * Determine whether the user can restore the model.
     *
     * @param  \App\Models\UserInterface  $user
     * @param  \App\Models\Admin  $admin
     * @return \Illuminate\Auth\Access\Response|bool
     */
    public function restore(UserInterface  $user, Admin $createdAdmin)
    {
        //
    }

    /**
     * Determine whether the user can permanently delete the model.
     *
     * @param  \App\Models\UserInterface  $user
     * @param  \App\Models\Admin  $admin
     * @return \Illuminate\Auth\Access\Response|bool
     */
    public function forceDelete(UserInterface  $user, Admin $createdAdmin)
    {
        //
    }
}
<?php

namespace App\Policies;

//use App\Models\Admin;
use App\Models\UserInterface;
use Illuminate\Auth\Access\HandlesAuthorization;

class UserPolicy
{
    use HandlesAuthorization;

    /**
     * Determine whether the user can view any models.
     *
     * @param  \App\Models\UserInterface  $user
     * @return \Illuminate\Auth\Access\Response|bool
     */
    public function viewAny(UserInterface $user)
    {
        if ($user->isAccessibleUsers()) {
            return true;
        }
    }

    /**
     * Determine whether the user can view the model.
     *
     * @param  \App\Models\UserInterface  $user
     * @param  \App\Models\Admin  $createdAdmin
     * @return \Illuminate\Auth\Access\Response|bool
     */
    public function view(UserInterface $user, Admin $createdAdmin)
    {
        // //
        // return $admin->id === $createdAdmin->user_id
        //             ? Response::allow()
        //             : Response::deny('You do not own this post.');
    }

    /**
     * Determine whether the user can create models.
     *
     * @param  \App\Models\UserInterface  $user
     * @return \Illuminate\Auth\Access\Response|bool
     */
    public function create(UserInterface  $user)
    {
        //
    }

    /**
     * Determine whether the user can update the model.
     *
     * @param  \App\Models\UserInterface  $user
     * @param  \App\Models\Admin  $admin
     * @return \Illuminate\Auth\Access\Response|bool
     */
    public function update(UserInterface  $user, Admin $createdAdmin)
    {
        //
    }

    /**
     * Determine whether the user can delete the model.
     *
     * @param  \App\Models\UserInterface  $user
     * @param  \App\Models\Admin  $admin
     * @return \Illuminate\Auth\Access\Response|bool
     */
    public function delete(UserInterface  $user, Admin $createdAdmin)
    {
        //
    }

    /**
     * Determine whether the user can restore the model.
     *
     * @param  \App\Models\UserInterface  $user
     * @param  \App\Models\Admin  $admin
     * @return \Illuminate\Auth\Access\Response|bool
     */
    public function restore(UserInterface  $user, Admin $createdAdmin)
    {
        //
    }

    /**
     * Determine whether the user can permanently delete the model.
     *
     * @param  \App\Models\UserInterface  $user
     * @param  \App\Models\Admin  $admin
     * @return \Illuminate\Auth\Access\Response|bool
     */
    public function forceDelete(UserInterface  $user, Admin $createdAdmin)
    {
        //
    }
}

5.Model 수정

Admin 모델과 User 모델로 나뉘어져 있는 상태이기에

Policy 에서의 모델 적용을 위해 UserInterface 를 만들어서 구현하게 합니다.

app/Models/ 에 UserInterface.php 에 

<?php

namespace App\Models;

interface UserInterface
{
    public function isAdmin();

    public function isAccessibleAdmins();

    public function isAccessibleUsers();

}

 Admin.php 모델은 

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use App\Models\UserInterface;

class Admin extends Authenticatable implements UserInterface
{
    use HasFactory;
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var string[]
     */
    protected $fillable = [
        'name',
        'email',
        'password',
        'type'
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array
     */
    protected $hidden = [
        'password',

    ];

    protected function getAdminType($type)
    {
        if($this->type === $type)
            return true;
        else
            return false;
    }

    public function isSuperAdministrator()
    {
        return $this->getAdminType('super_admin');
    }
    public function isAdministrator()
    {
        return $this->getAdminType('admin');
    }
    public function isModerator()
    {
        return $this->getAdminType('moderator');
    }
    public function isEditor()
    {
        return $this->getAdminType('editor');
    }

    public function isAdmin()
    {
        return true;
    }

    public function isAccessibleAdmins()
    {
        if ($this->isSuperAdministrator() || 
            $this->isAdministrator() ) {
            return true;
        }
    }

    public function isAccessibleUsers()
    {
        if ($this->isSuperAdministrator() || 
            $this->isAdministrator() ||
            $this->isModerator() ) {
            return true;
        }
    }

}

그리고 User.php

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Laravel\Jetstream\HasProfilePhoto;
use Laravel\Sanctum\HasApiTokens;
use App\Models\UserInterface;

class User extends Authenticatable implements UserInterface
{
    use HasApiTokens;
    use HasFactory;
    use HasProfilePhoto;
    use Notifiable;
    use TwoFactorAuthenticatable;

    /**
     * The attributes that are mass assignable.
     *
     * @var string[]
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
        'two_factor_recovery_codes',
        'two_factor_secret',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    /**
     * The accessors to append to the model's array form.
     *
     * @var array
     */
    protected $appends = [
        'profile_photo_url',
    ];


    public function isAdmin()
    {
        return false;
    }

    public function isAccessibleAdmins()
    {
        return false;
    }

    public function isAccessibleUsers()
    {
        return false;
    }
}

6.Seeder 수정

database/seeders/AdminSeeder.php 에 

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

use App\Models\Admin;

class AdminSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Admin::create([
            'name'     => 'super_admin',
            'email'    => 'super_admin@test.com',
            'type'     => 'super_admin',
            'password' => bcrypt('password'),
        ]);
        Admin::create([
            'name'     => 'admin',
            'email'    => 'admin@test.com',
            'type'     => 'admin',
            'password' => bcrypt('password'),
        ]);

        Admin::create([
            'name'     => 'moderator',
            'email'    => 'moderator@test.com',
            'type'     => 'moderator',
            'password' => bcrypt('password'),
        ]);
        Admin::create([
            'name'     => 'editor',
            'email'    => 'editor@test.com',
            'type'     => 'editor',
            'password' => bcrypt('password'),
        ]);

    }
}

 

7. php artisan migrate:fresh --seed

php artisan migrate:fresh --seed

한후  https://vuxy-003.test/admin/login 에 접속하고 위의 seeder 의 

ID: admin@test.com PW:password  로 접속하면 admins 메뉴와 users 메뉴에 접근이 가능합니다만 

ID: editor@test.com PW:password 로 접속하면 접근이 불가한걸 확인할 수 있습니다.

 

위처럼 Policy 로 접근 권한을 설정할 수 있습니다.

반응형
SMALL

댓글