こんにちは、かつコーチです。
自前で認証機能を作っていると、パスワードリセットやメール確認、アカウントロックなど、実装すべき機能がどんどん増えていきます。
この記事では、認証gemの定番であるDeviseの導入手順と、実務でよく使う設定を整理します。
has_secure_passwordとの使い分けも合わせて解説するので、どちらを選ぶべきか判断する材料にしてください。
Deviseの導入手順
Gemfileへの追加とインストール
まずはGemfileにDeviseを追加します。
# Gemfile
gem "devise"
追加したらbundle installを実行します。
bundle install
続いてDeviseのジェネレータを実行し、初期設定ファイルを生成します。
rails generate devise:install
このコマンドを実行すると、config/initializers/devise.rbとconfig/locales/devise.en.ymlが生成されます。
同時にターミナルへ、default_url_optionsの設定など残タスクの案内が表示されます。
見落とすと後述のエラーにつながるので、必ず全文を読んでおきましょう。
Userモデルの生成
次に、認証対象となるモデルをDeviseのジェネレータで作成します。
rails generate devise User
このコマンドで以下が自動生成されます。
app/models/user.rb(Deviseモジュールを含むモデル)db/migrate/xxxx_devise_create_users.rb(マイグレーションファイル)config/routes.rbへのdevise_for :usersの追加
生成されたuser.rbは次のような内容になっています。
# app/models/user.rb
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
end
マイグレーションを実行してテーブルを作成します。
rails db:migrate
必須の環境設定
Deviseを動かすには、config/environments/development.rbなどにメール送信元URLの設定が必要です。
# config/environments/development.rb
Rails.application.configure do
config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
end
本番環境(production.rb)にも、実際のドメインで同様の設定を追加してください。
これを忘れると、パスワードリセットメールのリンクが正しく生成されません。
Deviseとhas_secure_passwordの使い分け
実装コストと機能範囲の違い
has_secure_passwordは、Rails標準のbcryptベース認証機能です。
パスワードのハッシュ化と検証だけを提供する、最小限の認証機構(自分でログイン・ログアウトの処理を書く必要がある仕組み)です。
一方Deviseは、以下の機能をモジュール単位で標準搭載しています。
| 機能 | has_secure_password | Devise |
|---|---|---|
| パスワードハッシュ化 | ○ | ○ |
| ログイン・ログアウト | 自前実装 | 標準搭載 |
| パスワードリセット | 自前実装 | :recoverable |
| メール確認 | 自前実装 | :confirmable |
| アカウントロック | 自前実装 | :lockable |
| Remember me | 自前実装 | :rememberable |
どちらを選ぶべきか
判断軸はシンプルで、要求される機能の広さです。
社内ツールや学習用アプリのように、ログイン機能さえあれば十分なケースではhas_secure_passwordで十分です。
依存gemが少なく、認証フローを完全にコントロールできるメリットがあります。
一方、パスワードリセットやメール確認、アカウントロックなど、実務レベルのセキュリティ要件が求められるサービスではDeviseが有利です。
車輪の再発明を避けられ、実績あるgemに任せることでバグ混入のリスクも減らせます。
私の経験では、MVP開発の初期はhas_secure_passwordで素早く作り、機能要件が固まった段階でDeviseへ移行するケースもよく見かけます。
よくあるつまずきポイント・エラー対処
未ログイン時のリダイレクト設定
Deviseを導入した直後、未ログインユーザーを特定のページへ強制的にログインさせたい場面があります。
❌Before
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
end
このままだと、ログインしていないユーザーでもすべてのアクションにアクセスできてしまいます。
✅After
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
before_action :authenticate_user!
end
authenticate_user!はDeviseが提供するヘルパーメソッドです。
未ログイン状態でアクセスすると、自動的にログイン画面へリダイレクトされます。
default_url_options未設定によるエラー
私が初めてDeviseのパスワードリセット機能を試したとき、次のエラーに遭遇しました。
ActionView::Template::Error (Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true)
原因は、前述のdefault_url_optionsをdevelopment環境の設定ファイルに追加し忘れていたことでした。
パスワードリセットメール内のリンクを生成する際、Deviseはホスト名の情報を必要とします。
config/environments/development.rbにconfig.action_mailer.default_url_options = { host: "localhost", port: 3000 }を追加したところ、エラーは解消しました。
環境ごとに設定が必要な点を忘れないようにしてください。
まとめ
この記事のポイント
- Deviseは
gem "devise"追加後、rails generate devise:installとrails generate devise Userで導入する default_url_optionsの設定漏れは、メールリンク生成時のエラーの原因になりやすいhas_secure_passwordは最小構成、Deviseは機能豊富という違いを踏まえて選定する- 未ログインユーザーの制御には
authenticate_user!を使う
次に読むべき記事
- has_secure_passwordで認証機能を実装する
- CSRF対策とStrong Parametersでセキュリティを守る
タグ: Ruby on Rails, 上級者向け, 認証