シンプル!Laravel5.6で「権限つき」ログインさせる方法

さてさて、毎回言ってますけどLaravelには最初から強力な機能がたくさん備わっていて、開発効率が飛躍的に向上すること間違いなしだと思っています。

ただ、そんな中にあってもデフォルトではついていない機能もあって、「権限つきのログイン」もそのひとつです。

権限つきログインとは?

「権限つきログイン」というのは、ログイン機能にユーザータイプが分かる情報を追加したもので、

  • 管理者だけが閲覧できるページ
  • お客さんには見せたくないページ
  • 通常ユーザーだけに表示するイベント情報

といった、ユーザータイプでいろいろな切り替えができるようになります。

ということで、今回は練習として以下2つでログインができるようにしてみましょう。

  • owner ・・・ お店のオーナー
  • customer ・・・ お客さん

目指す機能

ゴールは、

  • お店のオーナーだけ表示できるページ
  • ログインしていれば誰でも表示できるページ

をつくることです。

では、実際にやってみましょう!

※前提として、「php artisan make:auth」で通常ログインができるようになっているものとします。まだやってない人は、【Laravel5.6】インストール直後にやること3点を参考にしてください。

データベースに「ユーザータイプ」項目を追加

Laravelのユーザーは「users」テーブルで管理されていますが、ここに「role(役割)」という項目を追加してユーザータイプを管理します。

では、データベース構造を変更するので、次のコマンドを実行しましょう。

php artisan make:migration add_role_to_users

これで、/database/migrationsの中に新しいファイルが作成されてるので、次のようにroleを追加するコードを追加します。

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

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

中身としては、

  • up()で「role」を追加する
  • down()で「role」を削除する

というコードが入っています。

※ちなみに、after()の部分は「role」の位置を変更する記述で、passwordの後にくるよう移動させています。もちろん一番最後でも問題ないですけど、なんだか「整頓されていない感」が出てしまうのでよく利用しています(笑)

コードが完成したら、マイグレーション(データベース構造の変更)を実行しましょう。

php artisan migrate

これで、roleを追加できました。

もし、もとに戻したい場合は、

php artisan migrate:rollback

で「role」を削除することができます。
この辺もLaravelの便利な機能のひとつですね!

では、テストユーザーとして「owner」と「customer」2人のデータを追加してみましょう。
データの追加はSeeder機能を使うと便利です。

コマンドからSeederファイルを作ってみましょう。

php artisan make:seeder UsersTableSeeder

これで、「/database/seeds」フォルダの中に「UsersTableSeeder.php」というファイルが作成されますので、以下のようにユーザー追加するコードを追加しましょう。

public function run()
{
    // オーナー
    \App\User::create([
        'name' => 'オーナー太郎',
        'email' => 'owner@example.com',
        'password' => bcrypt('xxxxxxxx'),
        'role' => 'owner'
    ]);

    // お客さん
    \App\User::create([
        'name' => 'お客花子',
        'email' => 'customer@example.com',
        'password' => bcrypt('xxxxxxxx'),
        'role' => 'customer'
    ]);
}

※ちなみに、roleは「roles」テーブルなどを作っておいた方がより整理しやすいんでしょうけど、今回はわかりやすさ重視で直接roleにデータを追加しています。もしくは、ピボットテーブルを使ってもいいかもしれません。

コードが書き終わったら、次のコマンドを実行してください。

php artisan migrate:fresh --seed

これで、「users」テーブルに「オーナー」と「お客さん」の2ユーザーを追加することができました。

ユーザータイプを判別するコードを書く(Middleware)

では、次にログインユーザーの「ユーザータイプ」を判別する部分を作っていきます。
後で説明しますが、ここで作るコードをrouteから呼び出すことになります。

利用するLaravelの機能は「middleware」です。
これで、ownerかどうかを判別する部分をつくっていきましょう。

これも専用コマンドがあるので、以下のように実行して下さい。

php artisan make:middleware OwnerAuth

すると、「/app/Http/Middleware」に「OwnerAuth.php」というファイルが作成されているので、そこに以下のようにコードを追加します。

    public function handle($request, Closure $next)
    {
        if(auth()->check() && auth()->user()->role == 'owner') {

            return $next($request);

        }

        return redirect('/');
    }
}

内容としては、

  • ログインしたユーザーの「role」が「owner」ならOK。
  • それ以外ならトップページにリダイレクトする

となります。

ちなみに、いちいちroleを呼び出すのはめんどくさいので、以下のように「users」テーブルにaccessorを作っておくと便利です。

public function getIsOwnerAttribute() {

    return (auth()->user()->role == 'owner');

}

今回で言うとこんな感じです。

if(auth()->check() && auth()->user()->is_owner) {

    return $next($request);

}

では、このmiddlewareをRouteから呼び出せるように「/app/Http/Kernel.php」に登録します。

use App\Http\Middleware\OwnerAuth;
protected $routeMiddleware = [
    /* 省略 */
    'owner_auth' => OwnerAuth::class,
];

※ネームスペース(use ****)も忘れずに!

これで呼び出しができるようになりました。

Routeに権限をセットする

では、次にRouteに権限をセットしていきます。サンプルとして、

http://*****.test/owner/home

が管理者専用のページになるようにしてみましょう。(つまり、お客さんユーザーなら表示せず、トップページにリダイレクトする)

LaravelのRouteファイルはいくつかりますが、基本は「/routes/web.php」です。
このファイルを開いて、さっき作ったMiddlewareをセットしましょう。

Route::group(['middleware' => 'owner_auth'], function () {

    Route::get('/owner/home', 'Owner\HomeController@index');

});

重要なのは、

Route::group(['middleware' => 'owner_auth'], function () { /* 省略 */ }

の部分です。これは、

  • グループを作ります。
  • そして、そのグループは「owner_auth」というMiddlewareをセットします

という意味になります。

つまり、実際の開発ではprefixを使って、以下のようにコード量を減らすことができると思います。

Route::group(['prefix' => 'owner', 'middleware' => 'owner_admin'], function () {

    Route::get('/home', 'Owner\HomeController@index');
    Route::get('/home2', 'Owner\HomeController@index2');
    Route::get('/home3', 'Owner\HomeController@index3');

});

では、Owner\HomeControllerを以下のコマンドで作成して中身を書いていきましょう。

php artisan make:controller Owner\\HomeController

テストなので、シンプルにOKだけを返すようにします。

public function index() {

    return 'OK';

}

はい。これで準備は完了です。
実際にログインしてみてみましょう。

オーナーとお客さんでログインして挙動をチェックする

この状態で、まずオーナーでログインして「http://*****.test/owner/home」にアクセスしてみます。

うまくいきました。
では、一旦ログアウトして「お客さん」ユーザーでログインしてみましょう。

トップページに自動リダイレクトされます。

これで「オーナー」専用ページを他のログインユーザーから守ることができるようになりました。

ちなみに

必見!Laravel(5.6)のBladeでできること「まとめ」でも触れましたけど、同じようにやるとBladeの中で「owner」か「customer」かを判別する独自のif文をつくることができます。

まず、「/app/Providers/AppServiceProvider.php」のboot()内に、次のコードを追加します。

\Blade::if('owner', function () {
    return (auth()->check() && auth()->user()->is_owner);
});

そして、テンプレートの中で、

@owner
    オーナーさん、いつもおつかれ様です!
@endowner

とすると、「owner」ユーザーだけに「オーナーさん、いつもおつかれ様です!」と表示することができます。これを使えば、「お客さんだけに特売情報を表示する」などもできますね!

おわりに

ということで、今回は権限つきログインについて解説してみました。実装にはいろいろ方法があるのでこれもひとつのやり方だと思ってください。

ではでは〜。