Laravelのルートがかなり多くなってきて、記述が大変&各ルートごとに細かな認可をどうするか考えた所、DBで管理することにしまあした。

モデルのイメージ

  • Action : すべてのリクエストパターン(routes/web.phpに定義するもの)をDBに登録
  • ActionRole : 中間テーブル
  • Role : 権限グループ
  • RoleUser : 中間テーブル
  • User : ユーザー

Actions : ルートに関する情報を記述

  • is_login : ログイン(認証)済みフラグ
  • label : ページ名(アクション名)
  • method : HTTPメソッド
  • name : ルート名( routeヘルパなどでリンク生成するときの名称)
  • controller : 実行コントローラー
  • action : 実行アクション
  • middleware : ミドルウェア

ActionRole : アクション(ルート)とRole(ロール)を紐付け

※アクションは頻繁に追加/変更差込などありそうなので、name(ルート名)で紐付けしている

  • action_name
  • role_id

Role : 権限

  • name(システム管理 / 商品管理 / 予算管理 / ユーザー管理 etc)

RoleUser

権限をユーザーに付与する中間テーブル

  • role_id
  • user_id

User : ユーザー

  • name
  • email
  • password

(その他通常のフィールド)

ルート実装

こんかい業務案件なのでアクセス少なく気にならない不可でそのままですが、toC向けアクセス多い場合は何かしらキャッシュ/ビルドの仕組み必要そう。

$actions = \App\Action::get(); //全てのアクション取得
foreach ($actions as $key => $action) {
    $methods = explode(',', $action->method);
    $uri = $action->uri;
    $name = $action->name;
    $middleware = explode(',', $action->middleware);
    $controllerAction = sprintf('%sController@%s', $action->controller, $action->action);
    Route::match($methods, $uri, $controllerAction)->name($name)->middleware($middleware);
}

認可実装(ミドルウェアなどで)

ざっくりと以下のように処理してます、のちのち運用フェーズではSQL一発で軽く確認できるような仕組みにしたい。

//actionを取得
$actionName = $request->route()->action['as'] ?? false;

//Actionモデルに認可判定処理関数を何かしら実装。
if(!Action::isAllow($actionName)){
    //権限無いよのエラー処理
}