CakePHP3でUsersテーブルにroleカラムを追加し、管理者と一般利用者で権限を分けたい
「このページは管理者画面だから、一般ユーザーはアクセス禁止」
「このページは普通の機能画面だから、全ユーザーがアクセスできるようにしたい」
上記みたいな状況ってありますよね。
そういう時はいくつか方法があります。
その中でも、「Usersテーブルにroleカラムを追加し、管理者と一般利用者で権限を分ける」という方法を説明します。
CakePHP3でのやり方です。
- まずはroleカラムを追加
- DBをいじって管理者ユーザー(admin)を作る
- それぞれのコントローラにisAuthorizedファンクションの内容を書いていく
- findAuthファンクションにて$this->Auth->user()で取得できる値にroleカラムを増やす
- 終わりに
【自分の環境】
macOS Catalina
PHP7.4.2
CakePHP3.8
MAMP5.7
Apache2.2
MySQL5.7
まずはroleカラムを追加
roleカラムを追加するマイグレーションからやっていきましょう。
(ターミナル)
./bin/cake bake migration AddRoleToUsers
これでマイグレーションファイルができます。
(マイグレーションファイル)
<?php use Migrations\AbstractMigration; class AddRoleToUsers extends AbstractMigration { public function up() { $table = $this->table('users'); $table->addColumn('role', 'string', [ 'default' => 'user', 'limit' => 255, 'null' => false, ]); $table->update(); } public function down() { $table = $this->table('users'); $table->removeColumn('role'); $table->update(); } }
カラム変更のマイグレーションなので、念のためロールバックできるようにup()とdown()に分けて書きます。
元々の値、デフォルトではuser(一般ユーザー)と入るようにします。
ほとんどのユーザーは一般ユーザーだからです。
文字数が長すぎるとか思う場合は「'limit' => 255」を調整してください。
これでマイグレーション実行します。
./bin/cake migrations migrate
DBを見るとroleカラムができていると思います。
DBをいじって管理者ユーザー(admin)を作る
DBをいじってroleに入っている値が「admin」のユーザーを作ります。
自分はphpMyAdminなので簡単に値の操作ができました。
このユーザーはどのページでもアクセスできるようにしていきます。
それぞれのコントローラにisAuthorizedファンクションの内容を書いていく
例えば私のサービスではUsersControllerでは「loginアクションとlogoutアクションには全ユーザーアクセスできるようにしたいが、indexアクションなどは管理画面として使用している」という状況があります。
この場合、loginアクションとlogoutアクションはadminでもuserでもアクセス可能で、その他のアクションはadminだけアクセス可能としたいです。
ただloginアクションに関しては明示的にアクセス可能とすると、ログイン機能がうまく働かなくなるので、ここでは一般ユーザーはlogoutアクションだけアクセス可能にしていきます。
※ややこしいですが、そういう仕様みたいです。
UsersControllerの一番下に、以下のようにisAuthorizedファンクションを記述します。
// 認証時のロールチェック public function isAuthorized($user = null){ // 役割がadminだったら全アクションにアクセス可能 if($user['role'] === 'admin'){ return true; } // 役割がuserだったらログアウトだけアクセス可能 if($user['role'] === 'user'){ if(in_array($this->request->getParam('action'),array('logout'))){ return true; } } // それ以外だったらfalseを返す return false; }
このように書きます。
すると、コメント通りですが、役割がadminだったら全アクションにアクセス可能で、役割がuserだったらログアウト画面だけアクセス可能になります。
ただ、まだやることはあります。
findAuthファンクションにて$this->Auth->user()で取得できる値にroleカラムを増やす
この操作をやらないと、isAuthorizedファンクションで上手くroleを判定できないです。
現在、UsersTable.php(Usersテーブル)のfindAuthファンクションはこのようになっているかと思います。
public function findAuth(\Cake\ORM\Query $query, array $options) { $query ->select(['id', 'name', 'mail', 'gender', 'pass']) // roleがない ->where(['Users.deleted IS' => NULL]); return $query; }
selectの引数に'role'を加えてあげてください。
public function findAuth(\Cake\ORM\Query $query, array $options) { $query ->select(['id', 'name', 'mail', 'role', 'gender', 'pass']) // roleを加えた ->where(['Users.deleted IS' => NULL]); return $query; }
このようにすると動くようになると思います。
指定したコントローラの管理者画面にはadminしか入れず、指定したコントローラ下で許可したlogout画面には全ユーザーがアクセスできます。
終わりに
いかがだったでしょうか。
自分のサービスではこのように実装しています。
少し長い説明になりました。
不明点があればコメントいただければと思います。
これ以外にもroute.phpで分けるなどのやり方もあるようです。
ありがとうございました。