Laravel5で社内専用サイト(6-1)

ACL(アクセスコントロールリスト)に関しては、パッケージを使おうと思ったのですが、私の環境が悪いのか、思うように動かないので、勉強がてら、自分で作ってみたいと思います。

ACLの基本設計

ACLを作るに当たり、下記のような基本設計を考えてみました。

  1. 全ユーザーからアクセスできるコントローラには、デフォルトのMiddleware(Authenticate.php)を使用する
  2. アクセス制限するコントローラには、新しいMiddleware(WinAcl.php)を使用する
  3. アクセス許可(permission)は、アクションメソッドごとに作成する
    ※セキュリティの関係で、いったんコントローラごとアクセス制限して、許可するアクションメソッドを登録します。
  4. テーブルは、roles、permissions、permission_roleの3つを追加作成する
    ※role_userテーブルも作成して、userがroleを複数持てるようにする方法もあるが、社内サイトなので、そこまでは必要ないと思い、role_userは今回作成しません。必要になれば、後から作成したいと思います。
  5. usersテーブルに、role_idフィールドを追加する
  6. adminロールは、全てのアクションメソッドにアクセスできるようにする

ACLテーブルの作成

まず、最初にテーブルを作成したいと思います。コマンドプロンプトから下記を入力し、データベースマイグレーションを作成します。

php artisan make:migration create_acl_tables

app/database/migrationsに生成されたファイルを下記のように修正します。

<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAclTables extends Migration
{
 /**
 * Run the migrations.
 *
 * @return void
 */
 public function up()
 {
 // ロールの作成
 Schema::create('roles', function (Blueprint $table) {
 $table->increments('id');
 $table->string('name')->unique();
 $table->string('display_name')->nullable();
 $table->string('description')->nullable();
 $table->timestamps();
 });
 //パーミッションの作成
 Schema::create('permissions', function (Blueprint $table) {
 $table->increments('id');
 $table->string('name')->unique();
 $table->string('display_name')->nullable();
 $table->string('description')->nullable();
 $table->timestamps();
 });
 //Pivotテーブルの作成
 Schema::create('permission_role', function (Blueprint $table) {
 $table->integer('permission_id')->unsigned();
 $table->integer('role_id')->unsigned();
$table->foreign('permission_id')->references('id')->on('permissions')
 ->onUpdate('cascade')->onDelete('cascade');
 $table->foreign('role_id')->references('id')->on('roles')
 ->onUpdate('cascade')->onDelete('cascade');
$table->primary(['permission_id', 'role_id']);
 });
 //usersテーブルにrole_idを追加
 Schema::table('users',function(Blueprint $table){
 $table->integer('role_id')->nullable()->after('name');
 });
 }
/**
 * Reverse the migrations.
 *
 * @return void
 */
 public function down()
 {
 Schema::drop('permission_role');
 Schema::drop('permissions');
 Schema::drop('roles');
 Schema::table('users',function(Blueprint $table){
 $table->dropColumn('role_id');
 });
 }
}

そして、コマンドプロンプトから、php artisan migrateを実行すると、3つのテーブル(roles、permissions、permission_role)が生成され、usersテーブルに新しくrole_idが追加されました。

モデルの作成

次に、モデルを作成します。php arisan make:modelで作成すると、app直下に作成されるので、新しくapp/Modelsフォルダを作成し、その中に下記の2つのモデルを作成します。

Roleモデルの作成

app/Models/Role.php

<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Role extends Model{
 
 public function Users()
 {
 return $this->belongsToMany('App\User');
 }
 public function Permissions()
 {
 return $this->belongsToMany('App\Models\Permission');
 }
}
  • 1行目:名前空間は、App\Modelsで指定します。
  • 5-8行目:Userモデルに対して、多対1のリレーションを設定します。
  • 9-12行目:Permissionモデルに対して、多対多のリレーションを設定します。

Permissionモデルの作成

app/Models/Permission.php

<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Permission extends Model{
 
 public function Roles()
 {
 return $this->belongsToMany('App\Models\Role');
 }
}
  • 1行目:上記と同様、名前空間のApp\Modelsを指定します。
  • 5-8行目:Roleモデルに対して、多対多のリレーションを設定します。

Userモデルの修正

Userモデルに下記を追加します。

app/User.php

public function Role()
 {
 return $this->belongsTo('App\Models\Role');
 }
 public function Permissions()
 {
 return $this->hasManyThrough('App\Models\Permission', 'App\Models\Role');
 }
  • 1-4行目:Roleモデルに対して、1対多のリレーションを設定します。
  • 7行目:Permissionモデルに対してhasManyThroughを設定します。
    ※hasManyThroughは、仲介するテーブルを通して、直接関連づけしていないテーブルへアクセスすることができます。この場合、usersテーブルは、Pivotテーブルを設定していない、permissionsテーブルへ、permission_roleテーブルを利用して、アクセスすることができるようになります。
    第1引数に、アクセスしたいModel名、第2引数に、仲介するモデル名を指定します。

本日は、以上です。

このエントリーを含むはてなブックマーク Buzzurlにブックマーク livedoorクリップ Yahoo!ブックマークに登録

トラックバック&コメント

この投稿のトラックバックURL:

コメントをどうぞ

このページの先頭へ