Sorceryを使用したログイン・ログアウト機能の実装手順
はじめに
本記事では、Rails 7でSorceryを使用したログイン・ログアウト機能の実装手順を、初学者向けに詳しく解説します。
現在RUNTEQで学習中であり、実際にDockerを使って初めてのアプリ制作での備忘録として記事を作成することにしました。
わかりにくい点などあるかと思いますが、ご了承くださいませ。
ユーザー登録については扱いません
Sorceryは現状開発が止まっておりメンテナンスも終了してます
責任は負いかねます
想定読者
- Rails初学者の方
- ログイン機能の実装に悩んでいる方
- Sorceryの基本を学びたい方
環境
Ruby: 3.3.6
Rails: 7.2.2.1
MySQL: 8.0
Docker使用
なぜSorceryを使うのか?
Devise vs Sorcery
認証機能の実装において、多くの場合DeviseとSorceryの2択で悩みましたが学習済みであるSorceryを採用しました。その他Sorceryには下記メリットがあります。
Sorceryのメリット:
-
シンプルさ
- 最小限の機能から始められる
- コードの理解がしやすい
- カスタマイズが直感的
-
学習効果
- 認証の仕組みが理解しやすい
- 段階的な機能追加が可能
- MVC(Model-View-Controller)の理解が深まる
-
柔軟性
- 必要な機能だけを実装可能
- 独自の要件に対応しやすい
1. Sorceryのインストール手順
Step 1: Gemfileの設定
# Gemfileに追加
gem 'sorcery', '0.16.3'
# インストールの実行
docker compose exec web bundle install
なぜバージョンを指定するのか?
- 予期せぬアップデートによるエラーを防ぐ
- チーム開発での環境統一
- 動作の安定性を確保
Step 2: Sorceryの初期設定
docker compose exec web rails generate sorcery:install
生成されるファイルと役割:
-
config/initializers/sorcery.rb
- Sorceryの設定ファイル
- 認証方法のカスタマイズ
- セキュリティ設定の管理
-
マイグレーションファイル
- ユーザー認証に必要なテーブルを作成
- 重要なカラム:
-
email
: ログイン識別子 -
crypted_password
: 暗号化されたパスワード -
salt
: パスワードの強度を高めるための文字列
-
この記事では扱いませんがユーザー登録には
このタイミングでマイグレーションファイルの生成と編集
docker compose exec web rails db:migrate コマンドの実行
モデルの編集などを行います
2. ルーティング設定
routes.rbの設定
Rails.application.routes.draw do
root "static_pages#top"
# ユーザー登録
resources :users, only: %i[new create]
# ログイン機能
get 'login', to: 'user_sessions#new'
post 'login', to: 'user_sessions#create'
delete 'logout', to: 'user_sessions#destroy'
end
各ルートの詳細な説明:
1.ログインフォーム表示
get 'login', to: 'user_sessions#new'
- HTTP GETメソッドを使用
- ログインページを表示するだけの役割
- フォームの入力情報は送信しない
2.ログイン処理
post 'login', to: 'user_sessions#create'
- HTTP POSTメソッドを使用
- フォームから送信された認証情報を処理
- セキュリティ上、必ずPOSTを使用
3.ログアウト処理
delete 'logout', to: 'user_sessions#destroy'
- HTTP DELETEメソッドを使用
- セッション情報を安全に削除
- RESTfulな設計原則に従う
3. コントローラーの実装
ApplicationControllerの設定
class ApplicationController < ActionController::Base
add_flash_types :success, :info, :warning, :danger
before_action :require_login
private
def not_authenticated
flash[:warning] = 'ログインしてください'
redirect_to login_path
end
end
重要な設定ポイント:
-
add_flash_types
- フラッシュメッセージのタイプを追加
- ユーザーへの適切なフィードバック表示に必要
-
before_action :require_login
- すべてのアクションで認証を要求
- 未ログインユーザーのアクセスを制御
UserSessionsControllerの実装
class UserSessionsController < ApplicationController
skip_before_action :require_login, only: %i[new create]
def new; end
def create
@user = login(params[:email], params[:password])
if @user
redirect_to root_path, success: 'ログインしました'
else
flash.now[:danger] = 'ログインに失敗しました'
render :new, status: :unprocessable_entity
end
end
def destroy
logout
redirect_to root_path, status: :see_other, success: 'ログアウトしました'
end
end
各メソッドの役割:
-
new
アクション- ログインフォームを表示
- 単純なビュー表示のみ
-
create
アクション- ログイン処理の実行
- 成功時:ルートページへリダイレクト
- 失敗時:ログインフォームを再表示
-
destroy
アクション- ログアウト処理
- セッション情報の安全な削除
4. ビューの実装
ログインフォーム(app/views/user_sessions/new.html.erb)
<div class="container mx-auto max-w-xl px-4">
<h1 style="color: #073472;" class="text-2xl font-bold text-center mb-8">ログイン</h1>
<%= form_with url: login_path, local: true do |f| %>
<div class="space-y-6">
<div class="mx-auto w-3/5">
<%= f.label :email, "メールアドレス", class: "block mb-2", style: "color: #073472;" %>
<%= f.email_field :email, class: "input input-bordered w-full", style: "background-color: #FFFFFF;" %>
</div>
<div class="mx-auto w-3/5">
<%= f.label :password, "パスワード", class: "block mb-2", style: "color: #073472;" %>
<%= f.password_field :password, class: "input input-bordered w-full", style: "background-color: #FFFFFF;" %>
</div>
<div class="text-center mt-8">
<%= f.submit "ログイン", class: "btn custom-text border-none hover:opacity-80", style: "background-color: #4981CF;" %>
</div>
</div>
<% end %>
</div>
このままではフラシュメッセージは反映されません。
フラッシュメッセージの反映には
ビューファイルの編集が必要ですがここでは扱いません。
5. Turboとの連携
ログアウトリンクの実装
<%= link_to "ログアウト", logout_path, data: { turbo_method: :delete }, class: "custom-text hover:opacity-80" %>
重要な設定ポイント:
-
data: { turbo_method: :delete }
の指定が必須 - Turboを使用したAjaxリクエストの実現
- RESTfulなHTTPメソッドの維持
動作確認方法
Railsコンソールでの確認
# ユーザーの存在確認
User.all
User.count
# 特定ユーザーの認証情報確認
user = User.first
user.crypted_password.present? # => true/false
user.salt.present? # => true/false
よくある実装ミス
-
セキュリティ関連
- パスワードの平文保存
- CSRF対策の無効化
- 適切なHTTPメソッドの未使用
-
ユーザー体験
- フラッシュメッセージの未実装
- エラーメッセージの不適切な表示
- リダイレクト先の誤り
-
実装上の注意
-
require_login
のスキップ忘れ - Turboメソッドの指定漏れ
- 不適切なルーティング設定
-
まとめ
Sorceryを使用したログイン機能の実装は、以下の点に注意して進めることで、安全で使いやすい認証システムを構築できます:
- 適切なルーティング設定
- 正しいHTTPメソッドの使用
- セキュリティを考慮した実装
- ユーザーフレンドリーなUIの提供
参考資料
以上で、Sorceryを使用したログイン・ログアウト機能の基本的な実装は完了です。
フラッシュメッセージは反映させるにはビューファイルの編集が必要となります
今後は、パスワードリセット機能など、より高度な機能を追加していくことができます。