WEBOPIXEL

Laravel8でCMSを作るチュートリアル(6) ユーザーロール(権限)の設定

Laravelロゴ

Posted: 2021.01.26 / Category: PHP / Tag: 

前回に続いて、Laravel8を使用して、コーポレートサイトでよくありそうなのお知らせを管理するCMSを作るチュートリアルの6回目です。(たぶん最終回)
今回はユーザーにロール(権限)を設定し、権限によってアクセスできるページを制限したいと思います。

Sponsored Link

作る機能

  1. 投稿一覧&詳細ページ
  2. 管理画面へのログイン機能
  3. 投稿管理(CRUD)機能
  4. ユーザーと投稿の関連付け(多対一:HasMany)
  5. 投稿のタグ分け(多対多:ManyToMany)
  6. ユーザーロール(権限)の設定

データベースの修正

ユーザーテーブルにroleという権限用のカラムを追加します。

database/migrations/XXXX_XX_XX_XXXXXX_create_users_table.php

public function up()
{
	Schema::create('users', function (Blueprint $table) {
		$table->id();
		$table->string('name');
		$table->string('email')->unique();
		$table->timestamp('email_verified_at')->nullable();
		$table->string('password');
		$table->tinyInteger('role')->default(1)->comment('権限');
		$table->rememberToken();
		$table->timestamps();
	});
}

シーダーにもroleを追加してみましょう。
今回は1,2だけ使います。

database/seeders/UserSeeder.php

\DB::table('users')->insert([
	[
		'name' => 'admin',
		'email' => 'admin@example.com',
		'email_verified_at' => now(),
		'password' => \Hash::make('123456789'),
		'role' => 1,
		'created_at' => now(),
		'updated_at' => now()
	],[
		'name' => 'yamada',
		'email' => 'yamada@example.com',
		'email_verified_at' => now(),
		'password' => \Hash::make('123456789'),
		'role' => 2,
		'created_at' => now(),
		'updated_at' => now()
	]
	// ...
]);

Gateの設定

Laravelでは権限によってアクセスを制限する場合はGateという機能を使うと簡単です。
AuthServiceProviderを下記のように編集します。

app/Providers/AuthServiceProvider.php

public function boot()
{
	$this->registerPolicies();

	// 管理者のみ許可
	Gate::define('admin', function ($user) {
		return $user->role === 1;
	});
}

これでroleが1だった場合のみアクセスするような条件を設定できるようになりました。
Gateを使うことでソースに1,2のようなよくわからない数値を書かないで済みます。

ルートの切り分け

試しにルートで設定してみます。
ユーザーの管理は管理権限でしかできないようにしてみましょう。

routes/back.php

Route::group(['middleware' => 'can:admin'], function () {
	Route::resource('users', 'UserController')->except('show');
});

middlewarecan:adminを指定して、制限したいページを囲むだけです。

ビューの切り分け

コントローラーにアクセスできないようにしたので、ナビゲーションのリンクボタンも管理者以外非表示にしたいですね。

resources/views/back/layouts/base.blade.php

@can('admin')
<li class="nav-item{{ Request::is('admin/users', 'admin/users/*') ? ' active' : '' }}">
	<a class="nav-link" href="{{ route('back.users.index') }}">ユーザー</a>
</li>
@endcan

@can('admin')@endcanで囲むだけです。簡単。