0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

OctoberCMS 管理画面実装テク:シンプルなリソースの権限管理を実装する

Posted at

概要

先日こちらの記事でLaravel Authorization Policyを使った管理画面におけるリソースアクセス制限について書きましたが、シンプルな権限管理であればモデルのイベントフックの方がよっぽどシンプルに実装できたのでメモ。Backend.Behaviors.FormControllerを実装しているコントローラを対象とします。

やり方

モデルイベントをフック

下記の例ではProductというモデルデータがロードされたタイミング(model.afterFetchイベント)で

Product::extend(function ($model) use ($user) {
   $model->bindEvent('model.afterFetch', function () use ($model, $user) {
       if (/* $modelと$userをつかって権限チェックをするロジックをここに記述 */) {
           // アクセス権がないときにtrueになるようにして、アクセス権なしだと例外を投げる
           throw new NoAccessRightToResourceException("アクセス権がありません");
       }
   });
});

ドキュメントではモデルのイベントフック登録は基本的に Plugin::boot() に記述すると書かれているが、結局は使用される前に登録されていればよい。本記事の場合、管理画面でのみ使用したいので、管理画面のコントローラのコンストラクタに記述すれば十分間に合う。

そして、権限がなかった時の処理を例外ハンドラとして登録する。こちらも同様にコンストラクタに記述するので十分。

App::error(function (NoAccessRightToResourceException $exception) {
    // アクセス権がない時の処理
    Flash::error($exception->getMessage());
});

基本的にはこれだけなのだが、これだけだと例外が上記で登録した例外ハンドラまで届かない場合がある。ここが落とし穴。

\Backend\Behaviors\FormController::update を見ると catch (Exception $ex) で全ての例外がキャッチされて$this->controller->handleError($ex); でハンドルされてしまっている。つまり、このままだと上記のようにApp::errorで登録したハンドラまで例外が届かない。なので、このhandleErrorメソッドをオーバーライドしてハンドラに登録した例外の場合はthrowし直すようにする。

public function handleError($exception){
    if ($exception instanceof NoAccessRightToResourceException) {
        // 例外を投げ直してApp::errorで登録したハンドラでハンドルさせる
        throw $exception;
    } else {
        parent::handleError($exception);
    }
}

以上

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?