[quads id=1]
今回は、Railsで認証機能を手軽に実装することができるGem「devise」でフレンドリーフォワーディング機能を実装する手順について解説したいと思います。希望ページに遷移するにはリクエスト時点のリクエストURLを取得・保存しなければならないため、やや面倒な実装が必要ですが、deviseを用いることで簡単に実装することができます。
フレンドリーフォワーディング機能とは
フレンドリーフォワーディング機能とは、新規登録やログイン・ログアウト後に元々アクセスしようとしていたページに遷移させる機能です。
例えば、ログイン前に編集ページにアクセスしたとします。その場合、まずはログイン画面に遷移しログインが求められますが、ログインを行うとそのユーザーの詳細ページにリダイレクトされてしまいます。
この時にユーザーの詳細ページではなく、元々アクセスしたかったページ、つまり編集ページにリダイレクトされる機能のことをフレンドリーフォワーディング機能と言います。
フレンドリーフォワーディング機能の実装手順
新規登録、ログイン・ログアウト機能といった、deviseでの認証機能の実装が一通り済んでいる前提で進めていきます。
まずはApplicationController
を以下のように編集します。
# Userモデルの場合
class ApplicationController < ActionController::Base
before_action :store_user_location!, if: :storable_location?
before_action :authenticate_user!
private
def storable_location?
request.get? && is_navigational_format? && !devise_controller? && !request.xhr?
end
def store_user_location!
store_location_for(:user, request.fullpath)
end
end
以下に当てはまる場合はセッションに値を保存しません。
- GETメソッドでない場合
- Deviseコントローラの画面である場合
- Ajaxリクエストの場合
before_action :store_user_location!, if: :storable_location?
private
def storable_location?
request.get? && is_navigational_format? && !devise_controller? && !request.xhr?
end
セッションから値を保存および取得するヘルパーメソッドであるstore_location_for
とstored_location_for
はDevise::Controllers::StoreLocation
に定義されています。
def store_user_location!
store_location_for(:user, request.fullpath)
end
あとはafter_sign_in_path_for
メソッドを上書きすることで、フレンドリーフォワーディング機能を実装することができます。
def after_sign_in_path_for(resource_or_scope)
stored_location_for(resource_or_scope) || super
end
ログイン後のリダイレクト先を個別に設定したい場合は、以下のように記述することができます。
def after_sign_in_path_for(resource_or_scope)
stored_location_for(resource_or_scope) || <飛ばしたいページのURL>
end
まとめ
- フレンドリーフォワーディング機能とは、新規登録やログイン・ログアウト後に元々アクセスしようとしていたページに遷移させる機能のこと
- GETメソッドでない場合、Deviseコントローラの画面である場合、Ajaxリクエストの場合はセッションに値を保存しない
store_location_for
とstored_location_for
はDevise::Controllers::StoreLocation
に定義されている
参考
How To: Redirect back to current page after sign in, sign out, sign up, update
今回は、認証機能を実装することができるGem「devise」でフレンドリーフォワーディング機能を実装する手順について解説しました。認証周りで欲しいと思った機能は大体deviseで実現できそうですね。