2

ユーザーを自分のアパートのデータのみを表示および編集できるように制限したいと考えています。session[:apartment_id] に彼らの apartment_id を保存しました。それで、私はCRUDを持っています.IDを変更してからデータを編集するためだけに /data/ID/edit を実行できないようにユーザーを制限したいと思います。これを行う良い方法はありますか、たとえば、何らかのスコープを通じて、またはすべてのアクションでコントローラーのすべてを検証する必要がありますか? 前もって感謝します。ドリジャン

編集: これはより詳細です: /data を行うときにユーザーのリストがあり、ID を持つユーザーに関する特定のデータを見たい場合は、/data/ID の例 /data/27 に移動します。私のデータベースでは、モデル データについて、ユーザーが属するアパートメントを示す行 apartment_id を取得しました。

ここで、セッション データに基づいて一部のユーザーの表示を制限したいと考えています。たとえば、ユーザーがログインすると、彼は session[:apartment_id] を取得しました。

そこで、セッション[:アパートID]とは異なるアパートIDを持つユーザーID=34に対して、例えば/data/34にアクセスできないようにユーザーを制限できるようにしたいと考えています。

また、ユーザーが /data にアクセスして、自分の見かけからユーザーを表示する場合のみ。

これをチェックするすべてのメソッドについて、各コントローラーでそれを実行できることはわかっていますが、一般的に、モデルのどこかでこれを実行できますか? ありがとうございました

4

3 に答える 3

3

Rails アプリに行レベル セキュリティを追加 する データベースを使用して Web アプリケーションを構築している場合、複数のユーザーが必要になる場合があります。これは、行レベル セキュリティと認証を追加することを意味します。

Rails は、Devise と呼ばれるクールな gem を支援します。Devise は User テーブルとビューを作成して、セッションで Web アプリに認証します。次に、各ビューに認証を追加して、そのビューを表示するための有効なセッションがあることを確認します。

それはすべてうまくいきますが、データベース内のデータをユーザーごとに制限するという私の他の問題は解決しません。そこで、Devise User モデル、特に id フィールドを使用することにし、他のデータベース テーブルによって id フィールドを含めるように変更しました (これを user_id と呼びました)。これはすべて、各 SQL クエリの一部としてセッション user_id を使用するモデル呼び出しのように、Rails アプリの残りの部分を微調整すると機能します。基本的な手順を説明します。これには詳細が含まれていますが、場合によっては即興で行う必要があります。

私の目に見えるプロセスは、Devise 固有の手順と行レベルのセキュリティ手順に分かれています。

手順を工夫する

Rails プロジェクトに Devise を追加する

    add devise gem to gem file

    gem ‘devise’

    bundle install



rails generate devise:install

(devise を rails app にインストールします - app ディレクトリのルートにあります)

rails g devise:views

(オプションの手順: これによりビューがコピーされるため、カスタマイズおよびスタイルを設定できます)

rails generate devise User

(ユーザーモデルを作成します)

bundle exec rake db:migrate

(テーブルを作成します - データベース構造を変更するには yml での権限が必要です)

残りのデバイス関連の手順

トップ div を application.html.erb に追加して、ユーザーがログインしているかどうかを確認し、ログイン ID または新しいユーザーとログイン リンクを表示します。

<div class=”top”&gt;

<p class=”notice”&gt;<%= notice %></p>

<p class=”alert”&gt;<%= alert %></p>

<p>

<% if user_signed_in? %>

  Logged in as <strong><%= current_user.email %></strong>.

  <%= link_to ‘Edit profile’, edit_user_registration_path %> |

  <%= link_to “Logout”, destroy_user_session_path, method: :delete  %>

<% else %>

  <%= link_to “Sign up”, new_user_registration_path  %> |

  <%= link_to “Login”, new_user_session_path %>

<% end %>

</div>

ログインしていないときに表示する「ゲスト」コントローラーとビューを作成しました-これをルートにするためにroutes.rbも更新しました-つまり、誰かが初めてサイトにアクセスしたときは、データではなくゲストコントローラーに連れて行く必要があります! まだセッションがありません。

更新されたゲスト/ルート コントローラー、特に、ユーザーがログインしている場合にログインしているコントローラーに移動するためのインデックス アクション

  if user_signed_in?

    redirect_to :controller=>’home’, :action=> ‘index’

  end

他のすべての data/loggedin コントローラーで、アクションの前にコントローラーの先頭に次を追加します。

before_filter :authenticate_user!

行レベルの手順

行レベル セキュリティ「RLS」が必要なテーブルを user_id 列で変更します。

mysql> ALTER TABLE mytable ADD COLUMN user_id VARCHAR(255) AFTER id;

users テーブルの有効な user_id でテーブルを更新します (これは、登録フォームで既にユーザーを作成していることを前提としています。または、Devise が最初のユーザー ID を 1 で開始しているように見えるため、単に 1 を使用します)

mysql> UPDATE mytable SET user_id = ( SELECT id FROM users WHERE email = ‘mememe@me.com’ );

テーブル挿入への user_id の追加を処理します

data/loggedin コントローラーの CREATE アクションで、パラメーター オブジェクトの user_id フィールドを更新します。

def create

params[:mytable][:user_id] = current_user.id

…

end

パラメータとして user_id を渡すことにより、選択/クエリを処理します

data/loggedin モデルでは、user_id を新しい my query スコープに渡し、その新しいスコープを他のスコープと結合します (必ず user_id を他のスコープに渡します。これを行う方法は他にもありますが、私はスコープが大好きです)。

scope :my, -> (user_id) { where(“user_id = ?”, user_id) }

scope :mylovelyquery, -> (user_id) { my(user_id).where(:mylovelyselectioncriteria=>”A”).order(“mysortfield”)  }

data/logged コントローラーで、 index アクションを変更して current_user.id を取得し、それを作成した ActiveRecord スコープに渡します。この手順は面倒で、頻繁に実行できます。RLS が必要なコントローラー インデックスまたは SELET を実行しているコントローラー アクションを探します。これは Ajax 呼び出しにも当てはまります。

def index

@user_id = current_user.id

@mytables = Mytable.my(@user_id).order(mylovelysortfield DESC”)

end

学んだ教訓

おそらく、データベースを取得する前に current_user.id を取得するのを忘れていたことが、最も電話を切ったことの 1 つです。

于 2014-03-15T21:11:35.993 に答える
1

ユーザーが has_many のアパートを持っている場合、通常はコントローラーでこれを行うことができます。

def edit
  current_user.apartments.find(params[:id])
end

これにより、現在のユーザーに属するアパートメントのみが検索されます。

アップデート

current_user オブジェクトがないように見えます...だから:

def edit 
  @apartment = Apartment.find(params[:id])
  redirect_to root_path, error: "You do not have access for this apartment"
end
于 2012-04-19T01:18:10.983 に答える
0

before_filterコントローラーで制限したい任意のアクションでa を使用できます。この件に関する読み物は次のとおりです。http://guides.rubyonrails.org/action_controller_overview.html#filters

于 2012-04-19T01:20:33.093 に答える