1

私の Rails アプリでは、アプリでユーザーを認証する Devise を使用しています。current_user.id現在ログインしているユーザーの UserIDなどの変数が表示されます。

私のアプリでは、すべてのユーザーが少なくとも 1 つのグループのメンバーです。どのユーザーも 1 つまたは複数の Trinket を作成でき、各 Trinket を自分のグループの 1 つに割り当てることができます。

だから、ここに私のモデルがあります:

User has_many :memberships
User has_many :groups, :through => :memberships

Group has_many :memberships
Group has_many :users, :through => :memberships
Group has_many :trinkets

Trinket belongs_to :group

だから私のモデルがあります!すべてがうまくいっています!

ユーザーがトリンケットを更新すると、そのトリンケットを自分のグループの 1 つに割り当てることができます。

しかし、セキュリティ上の欠陥があります。誰かが Trinket/edit または Trinket/new ページを表示し、HTML ソース コードをコピーし、フォーム内の<SELECT>または<INPUT>タグの値を変更すると、実際に Trinket を他の誰かの GroupID に送信できます。

モデルまたはコントローラーに検証を追加して、ユーザーが送信された値をデータベースに書き込む前に実際に使用できることを確認したいと思います。この場合、この Trinket の GroupID が内部の GroupID であるUser.find(current_user.id).groupsかどうかを確認したいのですが、Trinket モデルでその検証を行う方法がわかりません。

ユーザーが実際に値を割り当てるアクセス権を持っているものに値を割り当てようとしていることを確認する方法を知っている人はいますか? Devise または別の gem には、ユーザーが送信したデータの関連付けをチェックする方法がありますか?

現在のTrinketモデルファイルには次のものがあります:

attr_accessible :trinketname, :group_id
validates_presence_of :trinketname

これが理にかなっていることを願っています。助けていただければ幸いです。:-)

バージョン: Rails 3.2.13、Ruby 1.9.3p392、Devise 2.2.4。protect_from_forgeryapplication_controller.rb ファイルに含まれています。

4

2 に答える 2

1

ifアクション内にステートメントを入れることができます。これはおそらく正確ではありませんが、ポイントが伝わることを願っています:

 def create
   if trinket.group_id == current_user.group_id
     trinket.new(params[:trinket])
       if trinket.save
         redirect_to somewhere
       else 
         render :new
       end
   else      
    flash[:warn] "You're not allowed"
 end
于 2013-05-10T03:04:31.193 に答える
1

必要なのは承認です。

目的を達成するために、利用可能な多くの承認フレームワークのいずれかを使用することを検討してください。

CanCanRyan Bates 作は、最も広範囲にテストされた戦闘の 1 つです。

更新:アビリティでできること:

class Ability
  include CanCan::Ability

  def initialize(user)
    can :manage, Trinket, group: { id: user.group_ids }
  end
end
于 2013-05-10T03:25:39.950 に答える