フォーラム特権を実装するにはどうすればよいですか
-
05-10-2019 - |
質問
MVCフレームワークでPHPでフォーラムアプリケーションの開発を開始し、メンバーにアクセス許可を割り当てる段階に到達しました(例:読み取り、書き込み、更新、削除)。
今、私はデータベースのユーザーテーブルの下に5つの列を追加して、それらを1 |に設定できることを知っています。 0ですが、たとえば移動など、他のルールを追加したい場合、私にとってはあまりにも多くのように思えます。
そして、これらの特権をユーザーに個別に動的に割り当てるにはどうすればよいですか?
ビットマスクを使用することを聞いたことがありますが、続行する前に完全に理解できれば本当に良いでしょう。
これを実装する方法の例はありますか?
解決
あなたが説明した方法 - 列に保存されている個々の特権 - は、柔軟性を犠牲にして簡単です(あなたが気づいたように)。
Zuulの方法はさらにシンプルで、本質的にあなたと同じですが、「Table」ステートメントの必要性を回避します。ただし、正規化されておらず、簡単に照会できず、自己文書化もありません。
これらの両方の方法のもう1つの問題は、ユーザーベースが成長するにつれて、すべての人の特権を適切に設定するのがますます苦痛になることになることです。まったく同じ特権を必要とする多くのユーザーがいることに気付くでしょう。しかし、新しい特権を獲得するなど、ユーザーの特権を変更するには、個別に必要な各ユーザーにその特権を追加する必要があります。ピタ少佐。
フォーラムの場合、ユーザーごとの特権管理が必要ではないでしょう。匿名のユーザー、ログインユーザー、モデレーター、管理者などの特定のクラスのユーザーがいる可能性が高くなります。これにより、ロールベースのアクセス制御(RBAC)に適しています。このシステムでは、各ユーザーを役割に割り当て、役割に特権を付与します。特権は、「特権」テーブルに行として保存されます。したがって、簡素化されたデータベーススキーマは次のようになります。
PRIVILEGE
int id (primary key)
varchar description
ROLE_PRIVILEGE_JOIN
privilege_id (foreign key)
role_id (foreign key)
ROLE
int id (primary key)
varchar description
USER
int id (primary key)
int role_id (foreign key)
このパターンは、ユーザーの特権を扱う多くのアプリケーションで使用されます。誰もが特権テーブルに連続して持つことができるすべての特権を追加します。ロールテーブルにユーザーが持つ可能性のあるすべての役割を追加します。ロール_privilege_joinテーブルに適切にリンクします。
唯一の本当の欠点は、結合テーブルが使用されるため、「Can User X Do Y」クエリがやや遅くなることです。
他のヒント
アクセス許可ビットマスクは、バイナリとして表現される場合に最もよく理解され、各数字は許可をオンまたはオフにします。したがって、許可x、y、zが存在し、xとzにのみアクセスできる場合、 101
私には私に許可された最初と3番目の許可があるが、2番目の権限はないことを表します。バイナリ番号 101
10進数に相当します 5
, 、それがデータベースに保存されるものです。単一の小さな整数は、文字列やいくつかの小さな整数よりもはるかに効率的なオブジェクトです。
編集: 既存の変換関数を活用して、かなり迅速な実装を行うことがどれほど簡単かを理解しました。これがサンプルです。
<?php
function bitmask_expand($n) {
// 9 returns array(1, 0, 0, 1)
return str_split(base_convert($n, 10, 2));
}
function bitmask_compact($a) {
// array(1, 0, 0, 1) returns 9
return (int) base_convert(implode($a), 2, 10);
}
$ns = range(0, 7);
foreach($ns as $n) {
print_r($b = bitmask_expand($n));
echo bitmask_compact($b), "\n\n";
}
文字列に出入りするのではなく、ループを使用するとパフォーマンスが向上する場合がありますが、これは原則をかなり明確に示しています。
「役割」と呼ばれるテーブルを作成します。
CREATE TABLE Roles(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY(id),
rolename VARCHAR(30))
そこにあなたが望むどんな許可を貼り付けてください。次に、ユーザーを役割にリンクするために「Userroles」というテーブルを作成します。
CREATE TABLE UserRoles(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY(id),
UserId INT,
RoleID INT)
たくさんの柔軟性と簡単に構築できます(つまり、ワークフロー、ルールなど)(外国のキーも追加します)
それを複雑にする必要はありません。フィールド「例:許可」を使用して、次のようなことをします。
$ permissions = "1; 1; 0; 1";
あなたの懸念ではそれが読むところ:
読む-1(can)
書き込み-1(can)
更新-0(できない)
削除-1(can)
次に、チェックするときは、「爆発」を使用するだけです; "...
このようにして、テーブルを変更せずにいつでも多くのアクセス許可タイプを適用できます。したがって、テーブルを小さくし、クエリをより速くします!
それはあなたの問題の回避策です:)