基本的には、プロジェクト用にカスタムビルドされた「キックスタート」があります。このため、ユーザーコントロールのやり直しを検討しています。一般的なrbacについて多くの質問があることは知っていますが、階層的なrbacについては見つかりませんか?
要件は次のとおりです。
したがって、これらの要件が邪魔にならないように、ここでそれを行うことを考えています。
id | int | unique id
id | int | unique id
--------------|---------------------------------------------
title | varchar | human readable name
id | int | unique id
--------------|---------------------------------------------
module | varchar | module name
--------------|---------------------------------------------
title | varchar | human readable name
--------------|---------------------------------------------
key | varchar | key name used in functions
role_id | int | id from roles table
--------------|---------------------------------------------
user_id | int | id from users table
id | int | unique id
--------------|---------------------------------------------
permission_id | int | id from permissions table
--------------|---------------------------------------------
role_id | int | id from roles table
--------------|---------------------------------------------
grant | tinyint | 0 = deny, 1 = grant
id | int | unique id
--------------|---------------------------------------------
permission_id | int | id from permissions table
--------------|---------------------------------------------
user_id | int | id from users table
--------------|---------------------------------------------
grant | tinyint | 0 = deny, 1 = grant
まあ、実際にはそれの半分です、私が確信している部分、私が行き詰まっている部分は階層的な役割です。
だから、これをどのように設計しますか?私の考えは、データベースクエリを保存するには、ログイン時にアクセス許可マトリックスを作成し、セッションに保存するだけです。これにより、クエリがログインごとに1回だけ実行されるため、クエリが単純すぎる必要がなくなります。
問題は、継承を解決する前に、継承されたロールのアクセス許可を解決できるように、ロールの階層を知る必要があるということです。
ユーザー権限は簡単な部分であり、ユーザーごとの権限は基本的に最終的に解決されたグループです。
テーブルRoles
で再帰リレーションを使用し、ロール参照を別のレコードに作成することにより、ロール継承を実装する方法があります。
この関係は、Roles
レコード内に1 : n
継承を追加します。次のストアド関数を使用して、階層ツリー全体を取得できます。
CREATE FUNCTION `getHierarchy`(`aRole` BIGINT UNSIGNED)
RETURNS VARCHAR(1024)
NOT DETERMINISTIC
READS SQL DATA
BEGIN
DECLARE `aResult` VARCHAR(1024) DEFAULT NULL;
DECLARE `aParent` BIGINT UNSIGNED;
SET `aParent` = (SELECT `parent` FROM `Roles` WHERE `id` = `aRole`);
WHILE NOT `aParent` IS NULL DO
SET `aResult` = CONCAT_WS(',', `aResult`, `aParent`);
SET `aParent` = (SELECT `parent` FROM `Roles` WHERE `id` = `aParent`);
END WHILE;
RETURN IFNULL(`aResult`, '');
END
次に、次のようなすべてのgrantedパーミッションを取得します。
SELECT
`permission_id`
FROM
`Permission_Role`
WHERE
FIND_IN_SET(`role_id`, `getHierarchy`({$role}))
AND
grant;
十分でない場合は、継承のために別のテーブルを実行できます。
しかし、この場合、別の階層取得アルゴリズムが必要でした。
overridingの問題を解決するには、ロール権限とユーザー権限を取得する必要があります。次に、user
パーミッションにroles
パーミッションを上書きするsession
パーミッションを書き込みます。
また、Permission_Role
およびPermission_User
のgrant
列を削除することをお勧めします。 mapのそれぞれのすべての許可は必要ありません。 EXISTS
クエリを使用するのに十分です。レコードがある場合は許可が与えられ、そうでない場合は許可されません。すべての権限とステータスを取得する必要がある場合は、LEFT JOIN
sを使用できます。