web-dev-qa-db-ja.com

データベースのユーザーロール

ユーザーの役割(私の場合)をデータベースに保存する最も効率的な方法は何ですか?

私のユーザーテーブルは次のようになります。

id                         int(AI)
username                   varchar(80)
password                   varchar(255)

たとえば、権利は次のようになります。

ページを表示する権限が必要です:

  • ページ1
  • ページ2
  • ページ
  • ページ4

したがって、上記のケースでは、Page1およびPage2を表示する権利を持っているか、または単にPageを許可されている必要があります。

あなたはできる

  • 投稿を削除
  • 投稿を作成
  • 投稿を編集

ちょうどPage2

これらすべての組み合わせの可能性には、独自の役割があるはずです。

これをテーブルに格納する方法がわかりません。

私はこのようなテーブルを作成することを考えました:

role | page1 | page2 | page3 | page4 | page5 | page6 | delete | create | edit |
role1| yes   | yes   | no    | no    | no    | no    | yes    | yes    | yes  |

しかし、これを使用するには組み合わせが多すぎると思うので、これを行うにはより良い/効率的/簡単な方法が必要です。

だから私の質問は:

これを行うための最良/最も簡単な方法は何ですか?

3
Loko

ユーザーではなく、ロールの権限を定義する必要があります。ユーザーには、特定のページでのアクセスの種類を指定する役割が割り当てられます。次の図を見てください。

ロールの良い例は、「マネージャー」、「管理者」、「ユーザー」、「パブリック」です。この方法で行うことの利点は、役割を後で簡単に変更できることです。ページを追加して、管理者のみがページにアクセスできると決定した場合、ページの変更は管理者の役割を変更するのと同じくらい簡単で、その役割を持つすべてのユーザーが変更を行います。

RolePermissionsは、個々のページのアクセス許可を配置する場所です。名前(プログラムではキーとして参照するか、リソース名で直接参照しますが、キーで推奨します)と一連の権限が必要です。一般的な権限は、表示、更新、作成、削除などですが、ページに固有のカスタム権限には、少なくともいくつかの追加フィールドを作成する必要があります。表示は、ユーザーがそのページを表示できるかどうかを決定する特別な権限です。表示できない場合は、401エラーページまたはログインページにリダイレクトする必要があります。

また、特定のページの権限を見つけられなかった場合の対処方法の問題もあります。私の考えでは、ユーザーにはそのページを表示する権限がないと自動的に想定できますが、別の方法として、publicと呼ばれる削除できない(または少なくとも削除すべきではない)特別な役割を持たせることもできます。ユーザーの役割にアクセス許可が明示的に表示されていない場合は、パブリックロールのアクセス許可を自動的に参照して、適切な動作を確認できます。このように、最終的には、常にすべてのページとロールにアクセス許可を指定する必要がなく、非公開のアクセス許可ロールに対してより多くの寛大さを与えるアクセス許可を指定するだけで済みます。

ログイン情報はユーザーテーブルに保持され、権限とは別にする必要があります。また、@ Encaitarが彼の回答で述べたように、暗号化されているかどうかに関係なく、パスワード自体ではなくパスワードハッシュを処理するのが賢明です。

5
Neil

「良い」、「簡単」、および「効率的」は、すべての主観的で曖昧な用語であるだけでなく、頻繁に矛盾していますお互いに。データ表現の選択は、事実上常に、ある種類の良さと別の種類の良さとの間のトレードオフです。

各ページのすべての読み取り/書き込み/編集権限に個別のフィールドがあることで、最も単純なデータベースレイアウト、つまり列の束が作成されます。しかし、ページ1の編集権限をチェックするコードはすべて、ページ2、ページ3などで機能するためにduplicatedでなければならないため、プログラミングするのはより困難です。よりスマートなデータ構造がある場合、コードは単に代わりにparametrizedにする必要があります。重複するコードは一貫性の欠陥のよく知られた原因です。カットアンドペーストジョブは書くのが「簡単」ですが、通常、後で操作するのはそれほど簡単ではありません。そもそもプログラムの作成よりもプログラムの保守に多くの時間を費やすことが予想される場合は、保守のしやすさを優先する必要があります。たとえば、4番目のページが発明された後、カットアンドペーストをやり直すことは、通常、修正するのが難しい作業です。制限を表す定数を3から4に増やすのは簡単です。

構造化されたデータ表現(「ページ番号」、「ユーザーID」、「アクションタイプ」の列を持つリンクテーブルなど)を作成することの欠点は、計画にもう少し労力を費やし、本番環境でデータストレージを少し増やすことです。このコストが法外な場合もあります(たとえば、プログラムを4Kバイトに収める必要がある場合)、経験に基づく推測として、あなたはそのような状況ではないと想定しているため、メンテナンスを改善するために少し前に努力する必要がありますコードの読みやすさ。

2
Kilian Foth
  1. 暗号化されたパスワードであっても、パスワードをデータベースに保存しないでください。
  2. 認証と承認は異なる概念であり、データベースでスペース効率が非常に重要でない限り、それらを分割することを検討する必要があります。
  3. 権限のタイプごとの列とその権限に関連するオブジェクトの代わりに、* NIXファイルの権限と同様に、エンコードの権限を確認する必要があります。

パスワードをデータベースに直接保存する代わりに、パスワードをハッシュ(数学的にリバースすることは不可能です)して、そのハッシュの結果をデータベースに保存できます。次に、ユーザーがログインしようとしたときに、提案されたパスワードに対して同じハッシュを実行し、それをデータベースに保存されているものと比較します。一致する場合、ユーザーは正しいパスワードを入力しました。これには多くの問題があります。衝突の可能性があまり高くないハッシュ関数(複数のパスワードが同じ出力に解決される場合)、ハッシュ関数の複雑さ(ムーアの法則により、ブルートフォース攻撃がますます簡単になる)、およびは、事前に計算された「レインボーテーブル」であり、心配するパスワードとハッシュのペアを格納します(パスワードを疑似ランダム文字列で「ソルト」して、攻撃者が期待するものとは異なるものにする必要があります)。

ユーザー名/パスワード(またはハッシュ)と認証を別々にしておくと、論理ユニットが別々に保たれ、LDAPなどを使用する場合は後で分割できます。

* NIXファイルのアクセス許可では、8進数を使用して数値を加算します。つまり、所有者、グループ、その他の場合は、読み取りが+4、書き込みが+2、実行が+1になるため、所有者は751を読み取り、書き込み、実行します。権限を持つグループ内のすべてのユーザーに対して読み取りと実行を行い、他のすべてのユーザーに対してのみ権限を実行します。

1
Encaitar