0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Sorceryを使用したログイン・ログアウト機能の実装手順

Posted at

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のメリット:

  1. シンプルさ

    • 最小限の機能から始められる
    • コードの理解がしやすい
    • カスタマイズが直感的
  2. 学習効果

    • 認証の仕組みが理解しやすい
    • 段階的な機能追加が可能
    • MVC(Model-View-Controller)の理解が深まる
  3. 柔軟性

    • 必要な機能だけを実装可能
    • 独自の要件に対応しやすい

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

生成されるファイルと役割:

  1. config/initializers/sorcery.rb

    • Sorceryの設定ファイル
    • 認証方法のカスタマイズ
    • セキュリティ設定の管理
  2. マイグレーションファイル

    • ユーザー認証に必要なテーブルを作成
    • 重要なカラム:
      • 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

重要な設定ポイント:

  1. add_flash_types

    • フラッシュメッセージのタイプを追加
    • ユーザーへの適切なフィードバック表示に必要
  2. 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

各メソッドの役割:

  1. newアクション

    • ログインフォームを表示
    • 単純なビュー表示のみ
  2. createアクション

    • ログイン処理の実行
    • 成功時:ルートページへリダイレクト
    • 失敗時:ログインフォームを再表示
  3. 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

よくある実装ミス

  1. セキュリティ関連

    • パスワードの平文保存
    • CSRF対策の無効化
    • 適切なHTTPメソッドの未使用
  2. ユーザー体験

    • フラッシュメッセージの未実装
    • エラーメッセージの不適切な表示
    • リダイレクト先の誤り
  3. 実装上の注意

    • require_loginのスキップ忘れ
    • Turboメソッドの指定漏れ
    • 不適切なルーティング設定

まとめ

Sorceryを使用したログイン機能の実装は、以下の点に注意して進めることで、安全で使いやすい認証システムを構築できます:

  1. 適切なルーティング設定
  2. 正しいHTTPメソッドの使用
  3. セキュリティを考慮した実装
  4. ユーザーフレンドリーなUIの提供

参考資料

以上で、Sorceryを使用したログイン・ログアウト機能の基本的な実装は完了です。
フラッシュメッセージは反映させるにはビューファイルの編集が必要となります
今後は、パスワードリセット機能など、より高度な機能を追加していくことができます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?