23
30

More than 3 years have passed since last update.

アクセス制限(Ruby on Rails)

Posted at

プログラミングの勉強日記

2020年7月19日 Progate Lv.211
Ruby on RailsⅧ

アクション側で共通の変数の定義

 各アクションに対尾したビューファイルはapplication.html.erbの<%= yield %>の部分に代入され表示される。各コントローラの全アクションで共通する処理がある場合には、before_actionを使うと良い。before_actionを用いることで、アクションが呼び出される際に必ずbefore_actionの処理が実行されるので、全アクションで共通する処理を1か所にまとめられる。
 すべてのコントローラで共通する処理はapplicationコントローラにまとめられる。set_current_userメソッドを定義し、before_actionに指定する。

application_controller.rb
before_action :set_current_user
  @current_user=User.find_by(id: session[:user_id])
end

ログインしていないときのアクセス制限

 ログインしていない場合でもURLを直接入力するとアクセスできてしまう。@current_userがいない場合にはログインページにリダイレクトする。この処理は他のアクションや他のコントローラでも使いたいので、applicationコントローラとbefore_actionを用いて処理を共通化する。

application_controller.rb
def autheniticate_user
  if @current_user==nil
    flash[:notice]="ログインが必要です"
    redirect_to("/login")
  end
end

onlyを用いて各コントローラでbefore_actionを使うことで指定したアクションのみでメソッドを実行できる。各コントローラはapplicationコントローラを継承しているので、継承元のメソッドが使える。

user_controller.rb
before_action :autheniticate_user, {only: [:edit, :update]}
application_controller.rb
class ApplicaionController < ActionController::Base
  def set_current_user
    @current_user=User.find_by(id :session[:user_id])
  end
 ...

ログインユーザのアクセス制限

 applicationコントローラ内にログインユーザを制限するという意味のforbid_login_userメソッドを作成。ログインユーザが存在する場合、投稿一覧ページにリダイレクトする。メソッドの実行出にはbefore_actionを用いてonlyで適応したいアクションを指定する。

application_controller.rb
def fobid_login_user
  if @current_user
    flash[:notice]="ログインしています"
    redirect_to("/posts/index")
  end
end
home_controller.rb
before_action :forbid_login_user, {only: [:top]}
users_controller.rb
before_action :forbid_login_user, {only: [:name, :create, :login_form, :login]}

ユーザ編集ページのリンク

 ユーザ詳細画面の編集リンクを自分の詳細画面のときだけに表示されるようにする。ユーザ詳細ページでログインしているユーザでない場合には編集ページへのリンクを非表示にする。

users/show.html.erb
<%# 詳細ページのユーザidとログインしているユーザのidが等しい場合 %>
<% if @user.id==@current_user.id %>
  <% link_to("編集", "users/#{@user.id}/edit") %>
<% end %>

このままだと編集ページのURLを直接入力すれば編集ページに入れてしまう。なので、usersコントローラのeditアクションとupdateアクションに制限をかける。正しいユーザかを確かめるという意味のensure_current_userメソッドを用意して、ログイン中のユーザのidと編集したいユーザのidが等しいかを判定する。
 ログイン中のユーザのidは@current_user.idに編集したいユーザのidはparams[:id]にそれぞれ代入されている。params[:id]で取得できる値は文字列であり、数値である@current_user.idで比較してもfalseとなる。to_iメソッドを用いると文字列を数値に変換できる。

users_controller.rb
before_action :ensure_current_user, {only: [:edit, :update]}
def ensure_current_user
  if @current_user.id != params[:id].to_i
    flash[:notice]="権限がありません"
    redirect_to("/posts/index")
  end
end
23
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
30