LoginSignup
7
7

More than 3 years have passed since last update.

Laravel Breezeでユーザーの権限による認可

Last updated at Posted at 2021-02-02

Laravel BreezeでUserモデル一つ、roleで権限を分けてみました。
実運用はまだしていません。お試し中です。

Laravel Breezeのインストールはこちらを参照してください。
Laravel Breezeインストール済みであることで進めます。

権限は以下の3つにしてます。
admin company user
まずはusersテーブルにroleカラムを追加します。

migrations
class AddRoleToUserTable extends Migration
{

    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('role');
        });
    }

    public function down()
    {
        Schema::table('user', function (Blueprint $table) {
            $table->dropColumn('role');
        });
    }
}

ログイン後やユーザー登録後のリダイレクト先を割り振ります。

app/Providers/RouteServiceProvider.php
    public const HOME = '/';
    public const COMPANY = '/post/list';
});

userにcompanyを登録するためのメソッドcreatecompanyとstorecompanyをRegisteredUserControllerコントローラーにcreate、storeメソッドをコピーして追加。roleを割り振ります。
storeメソッドにもroleを指定してください。
会社登録用のregister画面を分けたいのでregister.phpをコピーしてregister-companyというビューも作ってます。
storecompanyで登録処理が終わったらCOMPANYに飛びます。

HTTP/Controller/Auth/RegisteredUserController.php

//追加画面
    public function createcompany()
    {
        return view('auth.register-company');   
    }
//登録処理
    public function storecompany(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|confirmed|min:8',
        ]);

        Auth::login($user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'role' => 'company',
            'password' => Hash::make($request->password),
        ]));

        event(new Registered($user));

        return redirect(RouteServiceProvider::COMPANY);
    }
});

管理者、会社、一般ユーザーの権限を分けるため、AuthServiceProviderにgateを書きます。

app/Providers/AuthServiceProvider.php
    public function boot()
    {
        $this->registerPolicies();

        //管理者か
        Gate::define('isAdmin',function($user){
           return $user->role == 'admin';
        });

        //会社か
        Gate::define('isCompany',function($user){
           return ($user->role == 'company' || $user->role == 'admin');
        });

        //POSTをアップデートできるのはuser->idが同じ
        Gate::define('update-post', function ($user, $post) {
            return $user->id === $post->user_id;
        });

        //POSTを消せるのはuser->idが同じ
        Gate::define('delete-job', function ($user, $post) {
            return $user->id === $post->user_id;
        });
    }
});

管理者以外companyをレジストできなくしたいので
Routeでgateを通れるisAdmin以外通れなくします。

routes/auth.php
// 管理者
Route::group(['middleware' => ['auth', 'can:isAdmin']], function () {
    Route::get('/registercompany', [RegisteredUserController::class, 'createcompany'])
                    //ログイン済みであればトップページにリダイレクトされる処理をコメントアウト
                    //->middleware('guest')
                    ->name('registercompany');

    Route::post('/registercompany', [RegisteredUserController::class, 'storecompany']);
                    //ログイン済みであればトップページにリダイレクトされる処理をコメントアウト
                    //->middleware('guest');
});

ログイン画面は同じメソッドで処理したいです。
ただしログイン後の画面は管理者とユーザーで分けたいので
AuthenticatedSessionControllerでユーザー権限引っ張って分岐します。

HTTP/Controller/Auth/AuthenticatedSessionController.php
    public function store(LoginRequest $request)
    {
        $request->authenticate();
        $request->session()->regenerate();
        //ユーザーによりログイン先を変更
        $user = Auth::user();
        if($user->role == 'admin'){
            return redirect(RouteServiceProvider::COMPANY);
        } elseif ($user->role == 'company') {
            return redirect(RouteServiceProvider::COMPANY);
        } elseif ($user->role == 'user') {
            return redirect(RouteServiceProvider::HOME);
        } else {
            return redirect('/')->with('flash_message', 'ユーザ一覧にアクセスが許可されていないユーザです。');
        }
    }

あとは各メソッドでgateを呼びます。これは編集

HTTP/Controller/PostEdit.php
class PostEdit extends Controller
{
    public function __invoke($id)
    {
        $user = Auth::user();
        $post = post::findOrFail($id);

        if (Gate::forUser($user)->allows('update-post', $post)) {
            // 渡されたユーザーはこのpost.editを表示できる。
            return view('post.edit', compact('post'));

        } elseif (Gate::allows('isAdmin')) {
            //adminは許可
            return view('post.edit', compact('post'));
        } else {
            return redirect('/')->with('flash_message', '編集できませんでした!');
        }      
    }
}

改修が必要ですがひとまず。

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7