Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Rails 8で基本的な認証ジェネレータが導入される(翻訳)

概要

元サイトの許諾を得て翻訳・公開いたします。

なお、本記事で取り上げられているのはいわゆるHTTP BASIC認証↓とは異なりますのでご注意ください。

参考: 11.1 HTTP BASIC認証 -- Action Controller の概要 - Railsガイド

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メソッドを用いてトークンを永続的なHttpOnly cookieに保存します。
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は、#52483has_secure_passwordに新しく追加されたコンフィグの一部です。トークンが失効するまでの期間はデフォルトで15分です。
edit
新しいパスワードを設定する画面をedit.html.erbビューテンプレートを用いて表示します。
update
ユーザーのパスワードを更新します。
更新に成功した場合はリダイレクトし、失敗した場合はアラートを表示します。
set_user_by_token
これはeditアクションやupdateアクションのbefore_actionコールバックです。リクエストのパラメータに含まれるpassword_reset_tokenを元に適切なユーザーの識別情報を取得します。

以上をまとめると、パスワードリセットのフローは以下のようになります。

パスワードリセットのフロー

🔗 現在の制限と考慮点

現在のauthenticationジェネレータは、メールアドレスとパスワードによる既存ユーザーのログインをサポートしていますが、新規アカウントの作成は行いません。今後のアップデートでユーザーアカウント作成機能やその他のカスタマイズが組み込まれる可能性もあります。

詳しくは以下のプルリクをご覧ください。

関連記事

Rails: Rodauthによるゼロからの認証システム構築チュートリアル(翻訳)

Rails: Deviseを徹底理解する(1)基礎編(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。