🦔

Rails アクセス制限

2023/04/12に公開

他のユーザーからのアクセスを制限する

ログインしているユーザー本人以外に、編集リンクが表示されなくても、
アドレスバーにURLを直接入力した場合アクセスできてしまう。。

これを防ぐため、以下のフローでアクセスを制限する。

ID:3のユーザー編集画面にアクセスさせて良いか判断する場合


/users/3/editにアクセス
👇
✅ログインしているユーザーIDが3と一致しているかチェック
👇YES
/users/3/editに対応するアクションを実行
👇
ユーザー(ID:3)の編集画面表示


✅ログインしているユーザーIDが3と一致しているかチェック
👇NO
投稿画面にリダイレクト


例として、
ユーザー情報の編集画面と更新処理に対しての処理を実行!!

  1. URLに含まれるユーザーidをparams[:id]で取得
  2. ログインしているユーザーのidをcurrent_user.idで取得
  3. 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