Rails アクセス制限
他のユーザーからのアクセスを制限する
ログインしているユーザー本人以外に、編集リンクが表示されなくても、
アドレスバーにURLを直接入力した場合アクセスできてしまう。。
これを防ぐため、以下のフローでアクセスを制限する。
ID:3のユーザー編集画面にアクセスさせて良いか判断する場合
/users/3/editにアクセス
👇
✅ログインしているユーザーIDが3と一致しているかチェック
👇YES
/users/3/editに対応するアクションを実行
👇
ユーザー(ID:3)の編集画面表示
✅ログインしているユーザーIDが3と一致しているかチェック
👇NO
投稿画面にリダイレクト
例として、
ユーザー情報の編集画面と更新処理に対しての処理を実行!!
- URLに含まれるユーザーidをparams[:id]で取得
- ログインしているユーザーのidをcurrent_user.idで取得
- 1と2のidが一致していなかった場合、 投稿一覧にリダイレクトする
users_controllerのedit、updateのアクションを編集
def edit
user = User.find(params[:id])
unless user.id == current_user.id
redirect_to post_images_path
end
@user = User.find(params[:id])
end
def update
user = User.find(params[:id])
unless user.id == current_user.id
redirect_to post_images_path
end
@user = User.find(params[:id])
@user.update(user_params)
redirect_to user_path(@user.id)
end
ログインしているユーザーのid以外の数値をURLに含んでアクセスして、
自動的に投稿画像一覧にページが切り替われば完成!
メソッドで処理をまとめよう
先ほどのコードで全く同じコードがあったのでまとめる!
この部分
user = User.find(params[:id])
unless user.id == current_user.id
redirect_to post_images_path
end
ログインしているユーザーのidとURLに含まれるidを比較し、
一致しなければ投稿画像一覧ページに移動する処理。
is_matching_login_userというメソッドにまとめる!
controllerの中でのみ使用するメソッドなのでpraivate以下に記述!
private
def is_matching_login_user
user = User.find(params[:id])
unless user.id == current_user.id
redirect_to post_images_path
end
end
end
このように置き換えられ、コードの量を削減できる!!
def edit
is_matching_login_user
@user = User.find(params[:id])
end
def update
is_matching_login_user
@user = User.find(params[:id])
@user.update(user_params)
redirect_to user_path(@user.id)
end
before_actionでアクション実行前に判断
メソッドとして処理をまとめたことで、before_actionを使用することができるようになる。
before_actionの仕組み
アクションを実行する前に、before_actionで設定したメソッドを実行する
ルーティングで指定したパスにアクセス
👇
ルーティングを確認する
👇
before_actionで設定したメソッドを実行する
👇
ルーティングで確認したアクションを実行する
👇
アクションに結びついたViewファイルを使ってページを表示させる
before_actionの構造
基本:コントローラーの全てのアクションに適用する場合
before:action:メソッド名
応用1:コントローラーのうち、適用しないアクションを選ぶ場合
before:action:メソッド名,except:[:アクション名]
応用2:コントローラーのうち、適用するアクションを選ぶ場合
before:action:メソッド名,only:[:アクション名]
今回の場合、"edit"と"update"のアクションの実行前に、
"is_matching_login_user"を実行させる。
class UsersController < ApplicationController
before_action :is_matching_login_user, only: [:edit, :update]
これに合わせて、"edit", "update"アクション内に記載された"is_matching_login_user"は削除できる!
以下の通りになれば OK!
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
@user.update(user_params)
redirect_to user_path(@user.id)
end
終わりの見えなかった課題3もあと明日明後日で完成できそう。
しっかり振り返りながらできていない部分もあるから
一旦課題3完成させてから
まだまだわかってないところを応用進めつつ、作り直しながら復習するつもり😶🌫️
パワーー
Discussion