ログイン自体していない人はauthenticate_user!でログイン画面に飛ばせるのは前回の記事の話。
前回の記事→https://qiita.com/JkzW1QJsgjPBxa/items/f834c85a420cd253d6bd
が、ログインはしてるけど別のIDの人はこれでは防げない。
URLを直接入力しちゃえば別のIDのページに行けちゃう。
例えばID1でログインしている人がてへっとID3の人の情報を覗いたり書き換えちゃったり消しちゃったりは、authenticate_user!では防げない。
ので、コントローラーにそれを防ぐ記述をしてみたよ。
(注意:未解決部分あり)
##before_action
コントローラーで、通ってほしいクラスを書くと、指定するアクションに行く前に通ってもらえる。
class ActorsController < ApplicationController
before_action :move_to_root, only: [:show, :create, :update] #←ココと
def new
@actor = Actor.find_or_initialize_by(user_id: current_user.id)
end
def create
@actor = Actor.new(actor_params)
# 略
end
def show
# 略
end
def update
# 略
end
private
def actor_params
params.require(:actor).permit(:comment, :image).merge(user_id: current_user.id)
end
def move_to_root #←ココ
# 中身は後で
end
end
今回はshow、create、updateアクションを指定しました。
今まで勉強してきた時はcreateやupdateじゃなくてnewに付ける感じだったんだけど、おそらく今回newアクションにfind_or_initializeを使っている関係で、これでは防げなかった。
ので、この書き方にしてみたんだけど、たぶん不格好というか大丈夫かな?と思っている、、、。
アドバイス等ご教授いただける方いらっしゃいましたらよろしくお願い致します。
↑の書き方をしていると、例えばID1の人がID3の編集ページをURLで指定して入っても、更新されるのはID1の人のページという状態でした。ので、ID3の人のページを書き換えることは防げている、けどroot_pathに戻る挙動ではないので、たぶん根本的に何か違う、、、
さて。
##move_to_rootの中身
こんな感じにしました。
def move_to_root
@actor = Actor.find(params[:id])
unless current_user.id == @actor.user_id
redirect_to root_path
end
end
redirect_toは↑のようにpathで指定することもできるし、アクションを指定することもできる
アクションで指定する場合は
def move_to_index
@actor = Actor.find(params[:id])
unless current_user.id == @actor.user_id
redirect_to action: :index
end
end
こういう書き方。
##まとめ
まとめ、というより今回はまだもやっとしたままのアウトプット。
うまくできる方法見つけれた時、また更新します。
それでは。