
認証機能って何?

プロ太先生、今まで作ってきた製品管理アプリなんですが、誰でも編集・削除できちゃうんですよね…

それは大問題だよね。例えば、君の日記が誰でも読めて、勝手に書き換えられたら嫌ですよね。

はい、、。LaravelではAuth::user()みたいな認証機能がありましたが、Railsでも似たような機能があるんですか?

もちろんあるよ!RailsにはLaravelのBreeze(ブリーズ)みたいに、認証機能を自動で作ってくれる便利なジェネレータがあるんだ。今日はそれを使って、「ログイン・ログアウト機能」を追加してみよう!
Step1: 認証機能の土台を作ろう

まずは、Rails付属の認証ジェネレータを使って基本機能を作るよ。
# 認証機能に必要なファイルを一括生成
$ bin/rails generate authentication

おお、これだけでいいんですか!Laravelだと composer require laravel/breeze
してから php artisan breeze:install
って感じでしたよね。

そうそう!Railsの場合は最初から入ってるから、追加インストールは不要なんだ。このコマンドで以下が自動生成されるよ。
- Userモデル: ユーザー情報を管理(Laravelと同じ)
- Sessionモデル: ログイン状態を管理
- コントローラ群: ログイン・ログアウト処理
- ビュー群: ログイン画面など

次に、データベースにテーブルを作ろう。
# データベースにusersテーブルとsessionsテーブルを作成
$ bin/rails db:migrate

これもLaravelの php artisan migrate
と同じ感覚ですね!
Step2: 最初のユーザーを作成しよう

テーブルができたら、実際にユーザーを作ってみよう。Railsコンソールを使うよ。
# Railsコンソール(対話モード)を起動
$ bin/rails console

LaravelでいうTinkerですね!

その通り!コンソールが開いたら、ユーザーを作成しよう。
# 新しいユーザーを作成(エラーが出たら例外を投げる)
store(dev)> User.create! email_address: "you@example.org", password: "s3cr3t", password_confirmation: "s3cr3t"
ここでのPoint!!
create!
の「!」= 「絶対に作る!失敗したらエラーを出して教えて!」なくても動くが実務ではつけるべき!!password_confirmation
= パスワードの確認入力(タイプミス防止)

LaravelのUser::create()と似てますが、パスワード確認が必要なんですね。

セキュリティを重視してるんだ。パスワードは自動でハッシュ化されるから、データベースには暗号化された状態で保存されるよ。
ここで、サーバーを再起動しよう!
# bcrypt gem(パスワード暗号化ライブラリ)を有効にするため再起動
$ bin/rails server
Step3: 認証機能を試してみよう

認証機能を設定したら、どうやって動作確認するんですか?

まずは、普通にアプリのトップページを開いてみよう。ブラウザで http://localhost:3000/
にアクセスしてみて。

あ!いきなりログイン画面が出てきました!

そう!認証ジェネレータは、デフォルトで「全てのページ」を認証必須にするんだ。つまり:
- トップページ(
/
) - 商品一覧(
/products
) - 商品詳細(
/products/1
) - 商品作成(
/products/new
)
全部ログインしないと見られない状態になってるんだよ。

なるほど!だから、どのページにアクセスしてもログイン画面になるんですね。

その通り!試しに http://localhost:3000/products/new
(商品作成ページ)にアクセスしても、同じログイン画面が出るはずだよ。さっき作ったメールアドレスとパスワードを入力してみよう。

ログインできました!これで製品の作成・編集ページにアクセスできるようになったんですね。

その通り!ブラウザがcookie(クッキー)という仕組みで認証情報を覚えているから、他のページに移動してもログイン状態が保持されるんだ。
Step4: ログアウト機能を追加しよう

次は、ログアウトボタンを追加しよう。app/views/layouts/application.html.erb
を編集するよ。
<!DOCTYPE html>
<html>
<!-- 省略 -->
<body>
<!-- ナビゲーションバー(全ページ共通のメニュー) -->
<nav>
<!-- ホームページへのリンク -->
<%= link_to "Home", root_path %>
<!-- ログイン済みの場合のみログアウトボタンを表示 -->
<%= button_to "Log out", session_path, method: :delete if authenticated? %>
</nav>
<!-- メインコンテンツエリア -->
<main>
<%= yield %> <!-- 各ページの内容がここに入る -->
</main>
</body>
</html>
ここでのポイント:
link_to
= 「〇〇へのリンクを作って」button_to
= 「〇〇用のボタンを作って」if authenticated?
= 「もしログイン済みなら」method: :delete
= 「DELETEリクエストで送信」(ログアウト=セッション削除)

LaravelのBladeテンプレートの @auth
ディレクティブと似てますね!

そうそう!authenticated?
がLaravelの Auth::check()
と同じ役割だよ。
Step5: 一部のページは認証なしでもOKにしよう

ストアの商品一覧や詳細ページは、お客さんが見られるようにしておきたいよね。

確かに!ネットショップで商品を見るのにログインが必要だったら、誰も買い物しませんね。

ということで、app/controllers/products_controller.rb
を編集しよう。
class ProductsController < ApplicationController
# index(一覧)とshow(詳細)は認証なしでもアクセス可能
allow_unauthenticated_access only: %i[ index show ]
# 以下省略...
end
ここでのPoint!!
allow_unauthenticated_access
= 「認証なしアクセスを許可する」only: %i[ index show ]
= 「indexとshowアクションのみ」%i[ ]
= シンボルの配列を作る簡単な書き方([:index, :show]
と同じ)

LaravelのMiddlewareで auth
を特定のルートから除外するのと似てますね!
Step6: 認証状態に応じてリンクを出し分けよう
商品一覧ページ

app/views/products/index.html.erb
で、ログイン済みの人だけに「新商品作成」リンクを表示しよう
<!-- ログイン済み の場合のみ新商品作成リンクを表示 -->
<%= link_to "New product", new_product_path if authenticated? %>
レイアウトファイル

さらに、app/views/layouts/application.html.erb
にログインリンクも追加しよう。
<nav>
<!-- ホームへのリンク -->
<%= link_to "Home", root_path %>
<!-- ログイン状態によってリンクを出し分け -->
<%= link_to "Login", new_session_path unless authenticated? %> <!-- 未ログインの場合 -->
<%= button_to "Log out", session_path, method: :delete if authenticated? %> <!-- ログイン済みの場合 -->
</nav>
ここがポイント!!
if authenticated?
= 「ログイン済みなら表示」unless authenticated?
= 「ログインしていなければ表示」

app/views/products/show.html.erbも更新しよう!
<h1><%= @product.name %></h1> <!-- 商品名を表示 -->
<!-- 一覧ページに戻るリンク(誰でも表示) -->
<%= link_to "Back", products_path %>
<!-- ログイン済みの場合のみ編集・削除機能を表示 -->
<% if authenticated? %>
<!-- 編集ページへのリンク -->
<%= link_to "Edit", edit_product_path(@product) %>
<!-- 削除ボタン(確認ダイアログ付き) -->
<%= button_to "Destroy", @product, method: :delete, data: { turbo_confirm: "Are you sure?" } %>
<% end %>
ここがポイント!!data: { turbo_confirm: "Are you sure?" }
= 削除前に確認ダイアログを表示
Laravel vs Rails の認証機能比較

最後に、LaravelとRailsの認証機能を比較してみたいです!


どちらも似たような機能があるんですね!でもアプローチが少し違う感じがします。

そう!Laravelは「Middleware」でフィルタリング、Railsは「Controller」で直接指定という違いがあるね。どちらも覚えやすいよ。
まとめ:今日学んだこと

今日の学習内容をまとめよう!
- 認証機能の基本設定
bin/rails generate authentication
で一括生成bin/rails db:migrate
でテーブル作成
- ユーザー作成
bin/rails console
でRailsコンソール起動User.create!
でユーザー作成
- ログイン・ログアウト機能
authenticated?
でログイン状態を判定button_to
でログアウト機能実装
- アクセス制御
allow_unauthenticated_access
で一部ページを認証なしで許可- ビューで
if authenticated?
を使って表示制御

ありがとうございました!これで安全な製品管理アプリができました。LaravelとRailsの違いも理解できて、とても勉強になりました!

セキュリティは開発の基本だから、しっかりマスターしておこうね。