序文: 認証に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