Rails 8で基本的な認証ジェネレータが導入される(翻訳)
DHHは最近、以下のAdd basic authentication generatorというタイトルのissueをRailsリポジトリに投稿しました。
今のRailsには、基本的な認証機能で必要となる主な材料はひととおり揃っているのに、それらをどう組み合わせたらよいかをまだよくわかっていない新規開発者が多いため、最終的にそうしたメカニズムを隠蔽するオールインワンのgemに頼っている。
#50446より
この問題に対処するため、Rails 8では基本的な認証をRailsアプリケーションに追加する作業をシンプルにできるジェネレータが導入されました。本記事では、この認証scaffoldに含まれるコンポーネントについて解説します。
🔗 Railsアプリケーションに認証を追加する。
Railsアプリケーションで、基本的な認証システムをセットアップするには、以下のコマンドを実行します。
bin/rails generate authentication
このコマンドは、認証を実装するときの基本となる重要なファイルセットを生成します(データベースでトラッキングされるセッションや、パスワードのリセット機能など)。生成されるscaffoldについてはgistをご覧ください。
このauthenticationジェネレータで作成されるコンポーネントを調べてみましょう。
🔗 モデルとマイグレーション
ユーザーアカウントやセッション管理の基盤を用意するため、以下の3つのモデルと、それらに対応するマイグレーションがセットアップされます。
セットアップには以下が含まれます。
- CreateUsersマイグレーション
- このマイグレーションはusersテーブルを作成します。このテーブルにはuniqueインデックス付きのemail_addressフィールドと、パスワードをハッシュ化して安全に保管するためのpassword_digestフィールドがあります。
- CreateSessionsマイグレーション
- このマイグレーションは、sessionsテーブルを作成します。このテーブルには、一意のtokenフィールドの他に、ユーザーのデバイスやネットワークの詳細情報を記録するためのip_addressフィールドとuser_agentフィールドがあります。Sessionモデルでは、has_secure_tokenを用いて一意のセッショントークンを生成します。
- Currentモデル
- このモデルは、リクエスト単位でステートを管理し、委譲先のuserにあるメソッドを介して現在のユーザーの情報へアクセス可能にします。
- bcrypt gemもGemfileに追加される
- このgemが存在しない場合は新規追加し、このgemがコメントアウトされている場合は、コメントアウトを解除してgemを有効にします。続いて、bundle installを実行してgemをインストールします。
🔗 認証のconcern
認証ロジックやセッション管理のコア部分は、Authentication concernにカプセル化されています。
- require_authentication
- これはbefore_action用コールバックであり、resume_sessionメソッドを用いて既存のセッションの復元を試みます。セッションが見つからない場合は、request_authenticationメソッドを用いてユーザーをログインページにリダイレクトします。
- resume_session
- find_session_by_cookieメソッドでcookieから取得した署名済みトークンを用いてセッションを復元します。セッションを現在のセッションとして設定してから、- set_current_sessionメソッドを用いてトークンを永続的な- HttpOnlycookieに保存します。
- authenticated?
- 現在のユーザーにアクティブなセッションがあるかどうかをチェックするヘルパーメソッドです。
- allow_unauthenticated_access
- このクラスメソッドは、require_authenticationコールバックで特定のアクションをバイパスするのに用います。
- after_authentication_url
- 認証後のリダイレクト先URLを返します。
- start_new_session_for(user)
- 指定のユーザーのデバイスやIPアドレスの詳細情報を渡して新しいセッションを作成し、現在のセッションを設定します。
- terminate_session
- 現在のセッションを破棄して、cookieからセッショントークンを削除します。
🔗 セッションを管理する
SessionsControllerはユーザーのセッション管理を処理するコントローラで、以下のアクションがあります。
- new
- ユーザーがログイン情報を入力するログインフォームを表示します。
 new.html.erbビューテンプレートファイルには、emailフィールドとpasswordフィールド、flashメッセージによる成功またはエラー表示機能、パスワード回復用リンクが含まれています。
- create
- ユーザーが入力したログイン情報でユーザーを認証します。
 新規セッションを作成してからafter_authentication_urlにリダイレクトします。認証に失敗した場合は、ログインフォームにリダイレクトしてエラーメッセージを表示します。
- destroy
- ユーザーのセッションを破棄してログインフォームにリダイレクトします。
以上を組み合わせた基本的な認証フローは、以下のような感じになります。

🔗 パスワードリセット機能
基本的なパスワードリセット機能には、「パスワードリセットのリクエスト開始」「メールによるリセット手順の送信」「パスワードの更新」が含まれます。PasswordsControllerは、これらを以下のアクションで管理します。
- new
- パスワードリセットのリクエスト送信用フォームを、new.html.erbビューテンプレートを用いて表示します。
- create
- パスワードリセットのリクエストを処理します。
 ユーザーが存在する場合はPasswordMailerでリセット用メールを送信し、メッセージを表示してリダイレクトします。
 送信されるメールにはパスワードリセットページへのリンクが含まれており、リンクにはpassword_reset_tokenパラメータがあります。このpassword_reset_tokenは、#52483でhas_secure_passwordに新しく追加されたコンフィグの一部です。トークンが失効するまでの期間はデフォルトで15分です。
- edit
- 新しいパスワードを設定する画面をedit.html.erbビューテンプレートを用いて表示します。
- update
- ユーザーのパスワードを更新します。
 更新に成功した場合はリダイレクトし、失敗した場合はアラートを表示します。
- set_user_by_token
- これはeditアクションやupdateアクションのbefore_actionコールバックです。リクエストのパラメータに含まれるpassword_reset_tokenを元に適切なユーザーの識別情報を取得します。
以上をまとめると、パスワードリセットのフローは以下のようになります。

🔗 現在の制限と考慮点
現在のauthenticationジェネレータは、メールアドレスとパスワードによる既存ユーザーのログインをサポートしていますが、新規アカウントの作成は行いません。今後のアップデートでユーザーアカウント作成機能やその他のカスタマイズが組み込まれる可能性もあります。
詳しくは以下のプルリクをご覧ください。
- Add basic sessions generator by dhh · Pull Request #52328 · rails/rails
- Add password reset to authentication generator by dhh · Pull Request #52472 · rails/rails
- Add a default password reset token to has_secure_password by dhh · Pull Request #52483 · rails/rails
 
       
                      
概要
元サイトの許諾を得て翻訳・公開いたします。
なお、本記事で取り上げられているのはいわゆるHTTP BASIC認証↓とは異なりますのでご注意ください。
参考: 11.1 HTTP BASIC認証 -- Action Controller の概要 - Railsガイド