LoginSignup
5
9

More than 5 years have passed since last update.

Laravel 5.7 + Tenancy Hyn マルチテナント基盤にlaravel-adminを導入

Last updated at Posted at 2018-12-18

Laravel 5.7 でフル機能マルチテナント・SaaS型アプリ基盤をゼロから3時間で構築するの付録記事。

LaravelでマルチテナントSaaS基盤を作ったはいいけど、管理画面構築を手抜き効率化したいのでlaravel-adminを導入する話です。

方針

  • LaravelでマルチテナントSaaS基盤をもとにアプリを開発する前に、各テナントごとに管理画面を持たせる基盤も作っておく。
  • テナントを作成したら、管理画面も自動的に準備完了になるようにする。
  • 管理画面ユーザーとフロントエンドユーザーは別のテーブルで管理する。ログイン管理も別。
  • フロントエンドのRoleやPermission管理画面も作りやすい状態にする。

参考記事

Laravel 5.7 laravel-adminを導入する
laravel-adminで管理画面を速攻で構築する。

では構築

Laravel 5.7 でフル機能マルチテナント・SaaS型アプリ基盤をゼロから3時間で構築する Part3が完了している状態が前提です。

  • Laravel 5.7が動作している。
  • Tenancy Hynが入っている。
  • laravel-permissionが入っている。
  • テナントを簡単に作ったり消したりできる。

laravel-adminをプロジェクトに入れます。

composer require encore/laravel-admin
php artisan vendor:publish


Encore\Admin\AdminServiceProvider
を選択。すると以下のようにファイルがコピーされます。

  Copied Directory [\vendor\encore\laravel-admin\config] To [\config]
  Copied Directory [\vendor\encore\laravel-admin\resources\lang] To [\resources\lang]
  Copied Directory [\vendor\encore\laravel-admin\database\migrations] To [\database\migrations]
  Copied Directory [\vendor\encore\laravel-admin\resources\assets] To [\public\vendor\laravel-admin]

さて、次はインストールですが、php artisan admin:installしてしまうとシステムデータベースにlaravel-admin用データベースが作られてしまいます。
マルチテナントなのでデータベースはテナント作成時にマイグレーションおよびシーディングするべきですから、そのように変更してからインストールします。

laravel-adminのインストールコンソールコマンドをextendして自前インストールコマンドを作る作戦を取ります。
laravel-adminで提供されるadmin:installArtisanコマンドでは、データベースの作成(Migration+Seeding)と、プログラムコードのコピーが行われていますが、データベースの作成はスキップしてコードのインストールだけ実施するようadmin:install4hynを作成します。
app/Console/Commands/LaravelAdminInstall.phpを新設。その中にArtisanコマンドadmin:install4hynを新設します。

php artisan make:command LaravelAdminInstall
app/Console/Commands/LaravelAdminInstall.php
<?php

namespace App\Console\Commands;

use Encore\Admin\Console\InstallCommand;

class LaravelAdminInstall extends InstallCommand
{
    /**
     * The console command name.
     *
     * @var string
     */
    protected $signature = 'admin:install4hyn';     // Our install command

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Install the admin package for Tenancy Hyn';       // Modified description

    /**
     * Install directory.
     *
     * @var string
     */
    protected $directory = '';

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function handle()
    {
        // $this->initDatabase();       // We do not migrate database at this moment.

        $this->initAdminDirectory();
    }

}

これを実行。

php artisan admin:install4hyn

するとアプリにコードが埋め込まれます。すべてapp/Admin以下に配置されていますね。

  Admin directory was created: \app\Admin
  HomeController file was created: \app\Admin/Controllers/HomeController.php
  AuthController file was created: \app\Admin/Controllers/AuthController.php
  ExampleController file was created: \app\Admin/Controllers/ExampleController.php
  Bootstrap file was created: \app\Admin/bootstrap.php
  Routes file was created: \app\Admin/routes.php

次に、テナント作成時にlaravel-adminに必要なテーブルが作られるように、Migrationファイルをdatabase/migrationsからdatabase/migrations/tenantに移動(コピーではなく)します。

xxxx_xx_xx_xxxxxx_create_admin_tables.phpの1個だけです。

テーブルの中身はlaravel-adminのコアにあるSeederを呼ぶ仕様みたいなので、''CreateTenant.php''(または親記事のおまけ1改造を行った場合はTenant.php)に追記。

app/Console/Commands/CreateTenant.php
...
use Artisan;
...
        $admin = static::makeAdmin($name, $email, str_random());  //これはもとからある
        static::makeAdminAdmin();  //これを追記
...
    private static function makeAdminAdmin(){
        $userModel = config('admin.database.users_model');

        if ($userModel::count() == 0) {
            Artisan::call('db:seed', ['--class' => \Encore\Admin\Auth\Database\AdminTablesSeeder::class]);
        }
    }
...

一応これでテナント作成したらhttp://テナント名.ベースURL/adminにアクセスできます。

image.png

User: admin, Password: adminでログインしようとすると、

Invalid catalog name: 1046 No database selected (SQL: select * from `admin_users` where `username` = admin limit 1)

これはlaravel-adminがテナントデータベースを見に行ってないためです。

今回はRouterの部分で、「laravel-adminのURLに入っていて、なおかつTenancyがテナントを認識していたら」、強制的にテナントデータベースを読みに行くようにapp/Admin/routes.phpを編集します。

app/Admin/routes.php
<?php

use Illuminate\Routing\Router;

// Tenancy patch
$hostname  = app(\Hyn\Tenancy\Environment::class)->hostname();
if(Request::is(config('admin.route.prefix')."*") && $hostname){
    Config::set('database.default', 'tenant');
}
...

config('admin.route.prefix')は、laravel-admin設定でURLのadminを好きなスラッグに変更できるので、それに対応させています。

では気を取り直してhttp://テナント名.ベースURL/adminからログインしてみましょう。

image.png

ちゃんとテナント専用管理画面が出ましたね。

あとはユーザー管理画面、権限管理画面を作成し、またアプリに必要な管理画面を作っていけばOKです。

残る課題

残念ながらこの方法は完ぺきというわけではなく、1つ問題が残っています。

テナント用に管理画面を開発しても、新しくテナントを作った時には、メニューバーがデフォルトのままになるし、権限設定も空の状態からスタートします。これは、メニューバーの設定がデータベースに記録されているため、開発内容がテナントのデータベースに記録されており、新しく作ったテナントには反映されないためです。もちろんRouteやControllerは存在するので、画面アクセスはできるんですけどね。

対処としては、いったんデフォルト状態を作ったテナントを準備し、そのデータベースからSeederを手作りしなくてはいけなさそうです。まあ、これくらいは仕方ないですね。

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