はじめに
Rails 8から導入された強力な標準機能である「認証ジェネレータ(bin/rails generate authentication)」。
これまでDeviseなどの外部Gemに頼っていたログイン機能が、標準コマンド一発で生成できるようになりました。
この標準機能を使っていて、「ログイン必須のページに直接アクセスして弾かれた後、ログインするとちゃんと元々見たかったページに飛ばしてくれる」という親切な挙動(いわゆるフレンドリーフォワーディング)に気づいた方も多いのではないでしょうか。
「これって裏側でどうやってるの?」と気になり、Deviseのようなブラックボックスではなく、Rails 8が生成したコードから直接その仕組みを読み解いてみました。
裏側にあるのは authentication.rb
Rails 8で認証機能を生成すると、app/controllers/concerns/ ディレクトリ配下に authentication.rb というモジュールが自動生成されます。
実は、このファイルの中にフレンドリーフォワーディングの仕組みが非常にシンプルに書かれています。
ステップ1:弾かれた時に、行きたかったURLを「記憶」する
未ログインのユーザーが、ログイン必須の画面(例:/users/edit)にアクセスしたとします。この時、コントローラーのフィルターによって以下の request_authentication メソッドが呼ばれます。
# app/controllers/concerns/authentication.rb
def request_authentication
# アクセスしようとしたURLをセッションに記憶する
session[:return_to_after_authenticating] = request.url
# ログイン画面へ強制リダイレクト
redirect_to new_session_path
end
ここでやっていることは超シンプルです。
session[:return_to_after_authenticating] というサーバー側のロッカー(セッション)に、ユーザーが本来アクセスしたかったURL(request.url)をこっそり保存してから、ログイン画面へリダイレクトさせています。
ステップ2:ログイン成功後、記憶したURLを「取り出す」
その後、ユーザーが正しい情報を入力してログイン(セッションの作成)に成功すると、行き先を決定するために以下の after_authentication_url メソッドが呼ばれます。
# app/controllers/concerns/authentication.rb
def after_authentication_url
session.delete(:return_to_after_authenticating) || root_url
end
この1行にRubyの美しさが詰まっています。
-
session.deleteを使って、先ほどロッカーに保存したURLを取り出しつつ、ロッカーを空にします(不要なデータが残り続けるのを防ぐため)。 -
||(or演算子)を使って、もしロッカーが空だった場合(直接ログイン画面にアクセスしてきた場合など)は、デフォルトのroot_url(トップページ)にフォールバックさせます。
最終的にログインのコントローラーは、このメソッドが返したURLに向かって redirect_to を実行しているだけなのです。
Rails 8 標準認証の最大のメリット
今回コードを読んでみて気づいた、Rails 8標準認証の最大のメリットは**「ブラックボックスがないこと」**です。
例えば、「うちのアプリは、どこからログイン画面に来たとしても、ログイン後は絶対にマイページ(/mypage)に飛ばしたい」という仕様変更があったとします。
もし巨大なGemを使っていたら、設定ファイルを書き換えたり、複雑なオーバーライドを調べる必要があります。しかしRails 8なら、自分の手元にあるコードを以下のように1行書き換えるだけで済みます。
# 変更前
def after_authentication_url
session.delete(:return_to_after_authenticating) || root_url
end
# 変更後(強制的にマイページへ)
def after_authentication_url
session.delete(:return_to_after_authenticating)
mypage_url # 常に行き先を固定
end
おわりに
便利な機能に出会った時、一旦立ち止まって
「これがない時代はどうやって実装していたんだろう?」
「裏側ではどんなコードが動いているんだろう?」
と疑い、ソースコードを直接読みにいくことで、Webシステム全体の解像度がグッと上がります。
Rails 8の認証コードは非常に読みやすくまとまっているので、Rubyの勉強としても一度 app/controllers/concerns/authentication.rb を上から下まで読んでみることをおすすめします!