ЯoomeR

プログラミング~実装とエラー解決と、時々、AI~

コントローラーでのアクセス制御[Rails]

勝手に編集や削除をされないよう、コントローラーでアクセス制御をつける方法を解説しています。

概要

  • 投稿したユーザー以外、編集や削除ができないようにコントローラーで設定
  • 使用するのはユーザー登録、テキスト投稿だけの超簡易アプリ

git clone してお手元で試せるよう、Githubで公開しています

別のユーザーの投稿を編集できてしまう

ユーザーを2人作成

1@1、2@2という2人のユーザーを作成しました。

文章の投稿

それぞれ1つずつ投稿を行いました。

編集ボタンの制御

投稿者自身がログインしている場合のみ、編集ボタンが表示されるようにします。

ただし、以下のようなURLを直接打ち込むことで、編集画面に遷移できてしまいます。

http://localhost:3000/posts/編集対象のpostのid/edit

コントローラーでアクセス制御

コントローラーにて、投稿者以外は編集できないように2つメソッドを追加します。

1.authenticate_user!

こちらを使うことで、「ログインしていない場合はログイン画面に遷移させる」という挙動を実装できます。

before_action :authenticate_user!,except: [:index]

2.「投稿者でない場合はトップページに遷移する」

次に、「投稿者でない場合はトップページに遷移する」というメソッドを定義します。

editに適用することで、直接URLを入力してもトップページに遷移するようにできました。

class PostsController < ApplicationController
  before_action :authenticate_user!,except: [:index]
  before_action :set_post,except:[:index,:new,:create]
  before_action :user_check,only:[:edit]

(省略)

  def user_check
    if current_user != @post.user
      redirect_to root_path
    end
  end

end

user_checkにて、「現在のユーザーと投稿したユーザーが不一致の場合、トップページに遷移する」という挙動を実装しています。

(user_checkより前にauthenticate_user!が呼び出されるため、current_user!というメソッドが使用できます。)

editへのアクセス制御だけでは不十分

updateには適用しなくても良いのでしょうか?

実は、適用する必要があります。

Chromeの検証を使用し、データを書き換えることができてしまうのです。

検証画面を使ってみましょう。

右クリックでEdit as HTMLを選択し、body内にフォームを作成します。

すると、トップページに編集用のフォームを作ることができてしまいます。

このフォームを使用すると、投稿者以外でも情報を書き換えることができてしまうのです。

よって、editだけでなくupdateにも適用する必要があるのです。

同じ方法で削除ボタンを作ることもできますから、destroyにも適用してあげましょう。

結論

  • ビューの条件分岐では不十分
  • editだけを守っても不十分。updateやdestroyも守る必要がある。
  • new、createの関係についても同様である。