3

序文: 認証にdeviseを使用しています。

許可されていないユーザーが別のユーザーの情報を表示、編集、または更新できないようにしようとしています。私の最大の懸念は、ユーザーが DOM のフォームを別のユーザーの ID に変更し、フォームに入力し、更新をクリックすることです。以下のようなものが機能するはずですが、そうではありません。SO に関する投稿では、validate_current_userメソッドをパブリック レルムに移動することが推奨されていましたが、それもうまくいきませんでした。

私が間違っていることは明らかですか?または、私がやろうとしていることへのより良いアプローチはありますか?

UsersControllerはこのように見えます:

class UsersController < ApplicationController
  before_filter :authenticate_admin!, :only => [:new, :create, :destroy]
  before_filter :redirect_guests

  def index
    redirect_to current_user unless current_user.try(:admin?)

    if params[:approved] == "false"
      @users = User.find_all_by_approved(false)
    else
      @users = User.all
    end
  end

  def show
    @user = User.find(params[:id])
    validate_current_user
    @user
  end

  def new
    @user = User.new
  end

  def edit
    @user = User.find(params[:id])
    validate_current_user
    @user
  end

  def create
    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
        format.html { redirect_to @user, :notice => 'User was successfully created.' }
      else
        format.html { render :action => "new" }
      end
    end
  end

  def update
    @user = User.find(params[:id])

    validate_current_user

    respond_to do |format|
      if @user.update_attributes(params[:user])
        format.html { redirect_to @user, :notice => 'User was successfully updated.' }
      else
        format.html { render :action => "edit" }
      end
    end
  end

  private

  def redirect_guests
    redirect_to new_user_session_path if current_user.nil?
  end

  def validate_current_user
    if current_user && current_user != @user && !current_user.try(:admin?)
      return redirect_to(current_user)
    end
  end

end

メソッドは次のauthenticate_admin!ようになります。

  def authenticate_admin!
    return redirect_to new_user_session_path if current_user.nil?

    unless current_user.try(:admin?)
      flash[:error] = "Unauthorized access!"
      redirect_to root_path
    end
  end

編集 - 「うまくいかない」とはどういう意味ですか?

明確にするために、別のユーザーのアカウントを「ハッキング」しようとすると、次のエラーが表示されます。

このアクションでレンダリングやリダイレクトが複数回呼び出されました。render または redirect のみを呼び出すことができ、アクションごとに最大 1 回しか呼び出せないことに注意してください。また、redirect も render もアクションの実行を終了しないことに注意してください。そのため、リダイレクト後にアクションを終了する場合は、「redirect_to(...) and return」のようなことを行う必要があります。

メソッドコードを個々のコントローラーアクションにインラインで配置すると、それら機能します。でも、DRYじゃないからやりたくない。

また、試したことを明記する必要があります。

def validate_current_user
  if current_user && current_user != @user && !current_user.try(:admin?)
     redirect_to(current_user) and return
  end
end
4

4 に答える 4