第6回「Rails基礎力を固める 模擬問題で学ぶ試験対策」認証・認可とコントローラ設計

みなさん、こんにちは。

Rails アプリケーションにおいて、認証(Authentication)と認可(Authorization)は、安全な設計を行ううえで避けて通れない重要なテーマです。ログインしているかどうかを確認する処理と、そのユーザーに特定の操作を許可するかどうかを判断する処理は、似ているようで本質的に役割が異なります。この違いを正しく理解し、コード上でも明確に分離できるかどうかが、コントローラ設計の質を大きく左右します。

認証とは「そのユーザーが誰であるか」を確認すること、すなわちログイン状態を検証する仕組みです。一方、認可とは「そのユーザーがその操作を実行してよいか」を判断する権限制御のことを指します。Rails では多くの場合、current_user メソッドを通じてログインユーザーを取得し、before_action と組み合わせながら制御を行います。

これらの処理をどこに、どのように書くかは、Rails の設計思想を理解しているかどうかを問われるポイントでもあります。今回も引き続き、コントローラ設計の視点から、認証と認可をどのように整理し、安全で読みやすいコードとして実装していくべきかを確認していきましょう。

目次

認証:current_user の役割

Rails における認証の基本は、セッションを利用してログイン状態を管理することです。一般的には、ログイン時に session[:user_id] のようにユーザーIDをセッションに保存し、current_user メソッドを通じてそのユーザーを取得します。

def current_user
  @current_user ||= User.find_by(id: session[:user_id])
end

このメソッドは、セッションに保存されたユーザーIDをもとにデータベースからユーザーを取得し、インスタンス変数にキャッシュしています。current_user が nil の場合は、ログインしていない状態であると判断できます。

ログインが必要なページでは、before_action を使って認証処理を共通化します。

before_action :authenticate_user

def authenticate_user
  redirect_to login_path unless current_user
end

このようにしておくことで、各アクションに毎回ログインチェックを書く必要がなくなります。認証処理をアクション内部ではなく、コントローラの冒頭で明示的に宣言するとRailsらしい設計になります。

認可:その操作を許可するか

一方、認可は「ログインしているか」ではなく、「そのユーザーがその操作をしてよいか」を判断する処理です。たとえば、「投稿は作成者のみ編集できる」という要件がある場合、単にログインしているだけでは不十分です。

before_action :authorize_user, only: [:edit, :update]

def authorize_user
  redirect_to posts_path unless @post.user == current_user
end

ここでは、対象となる投稿(@post)を取得したうえで、その投稿の所有者と現在のログインユーザーを比較しています。この順序が重要です。まずリソースを取得し、その後で権限を確認するという流れが、認可の基本パターンになります。

認証と認可を混同しないようにしましょう。ログインしていることは前提条件に過ぎず、実際に操作を許可するかどうかは別の判断になります。どのタイミングで判定を行うべきか、before_action をどのように使い分けるかといったポイントが設計上、重要になります。

模擬問題

問題1

次のうち、ログインしていないユーザーを制限する実装として最も適切なものを1つ選びなさい。

def index
  redirect_to login_path unless current_user
end
before_action :authenticate_user
if current_user.nil?
  session[:user_id] = nil
end
render :login unless current_user

正解

2

解説

Rails では、ログインチェックのような共通処理は before_action によってまとめて宣言するのが基本です。これによって、各アクションに同じコードを繰り返し書く必要がなくなり、コントローラ全体の構造が明確になります。認証処理は「アクションの前提条件」であるため、アクション内部ではなく、コントローラの冒頭で宣言されるのが理想的です。

選択肢1も動作自体はしますが、各アクションに同じ記述を繰り返すことになり、保守性が低下します。Rails の設計思想である「共通処理の抽出」に反しています。

選択肢3はログインしていない場合にセッションを nil にしていますが、そもそもアクセスを制限していないため認証処理にはなっていません。

選択肢4はログイン画面を描画するだけで、URLが変更されません。本来ログインページは専用のルーティングにリダイレクトするべきであり、単に render するのは設計として適切とはいえません。

この問題のポイントは、「動くコード」ではなく「Railsらしい設計」を選べるかどうかです。試験では、こうした設計思想を理解しているかどうかも問われます。

問題2

投稿の編集権限を制御するコードとして最も適切なものを1つ選びなさい。

if @post.user_id == params[:user_id]
if @post.user == current_user
if session[:user_id] == @post.id
if current_user.admin = true

正解

2

解説

認可の基本は、「現在ログインしているユーザー」と「対象リソースの所有者」を直接比較することです。選択肢2はサーバー側で信頼できるデータ(データベース上の所有者情報)と、ログインユーザーを照合しているため、安全かつ明確です。

選択肢1は、ユーザー入力である params を認可判定に使っています。params はユーザーが改ざん可能な値であり、これを信用すると他人の投稿を編集できてしまう危険があります。認可処理において、params をそのまま比較対象に使うのは設計上、NGです。

選択肢3は論理的に誤りです。session[:user_id] はユーザーIDであり、@post.id は投稿IDです。比較対象が異なります。

選択肢4は代入演算子 = を使っているため誤りです。本来は比較演算子 == を使う必要があります。

問題3

次の説明のうち、認可(Authorization)に該当するものとして最も適切なものを1つ選びなさい。

  1. ユーザーがログインしているか確認する
  2. メールアドレスとパスワードを照合する
  3. 管理者のみ削除操作を許可する
  4. セッションを作成する

正解

3

解説

認可(Authorization)とは、「そのユーザーに特定の操作を許可するかどうか」を判断する仕組みです。選択肢3の「管理者のみ削除操作を許可する」は、操作権限の制御であり、認可に該当します。

一方、選択肢1・2・4はすべて認証(Authentication)に関する処理です。「ログインしているか確認する」「メールアドレスとパスワードを照合する」「セッションを作成する」これらは、ユーザーが誰であるかを確定させるための処理です。

試験では、認証と認可を混同させる選択肢が出題されることがあるため、役割の違いを説明できるようにしておくことも重要です。

まとめ

今回のテーマである認証と認可は、Railsアプリケーションの安全性を支える中核的な仕組みです。ログインしているかどうかを確認する処理と、そのユーザーに特定の操作を許可するかどうかを判断する処理は、似ているようで役割がまったく異なります。この二つを明確に分離して設計できるかどうかが、コントローラの質を大きく左右します。

安全で読みやすいコントローラには共通した特徴があります。認証は before_action で共通化され、認可はリソースを取得した後に明示的に判定されます。この区別が曖昧になると、ロジックは複雑になり、思わぬバグや脆弱性を生みやすくなります。また、ユーザー入力である params を安易に信用せず、処理の責務が整理されているため、各アクションの意図が明確です。Rails らしい設計とは、機能を増やすことではなく、処理を適切な場所に配置し、責務を分離することにあります。単にコードが動くかどうかではなく、「どこに何を書くべきか」という視点も重要です。

次回も引き続き、認証・認可をテーマに扱います。今回は基本的な構造と役割の整理でしたが、次回は管理者フラグを使った権限制御や、ネストされたリソースにおける認可設計など、より実践的なケースに踏み込んでいきます。段階的に理解を深めていきましょう。

Rails7認定ベーシック試験について

全国300か所で通年実施しています。詳細は以下をご覧ください。

また、450ページを超える教科書も安価に出版しています。学習にあたってご活用ください。詳細は以下をご覧ください。https://railsce.com/rails7basic

Rails 7 技術者認定ベーシック試験公式教科書ベータ版著者:小澤昌樹 発行:Rails技術者認定試験運営委員会価格(税込):ペーパーバック版 2,497円 Kindle版 1250円ページ数:471ページ

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次