はじめまして!オンラインスクールでRuby on Rails勉強中の初学者です。
この度卒業制作として、「甲子園NOW!」というアプリを作成いたしました。
甲子園球場の試合中の盛り上がりを可視化でき、ファン同士の交流を促進するアプリです。
そのアプリの作成中に発生した問題たちを記事にしていけたらと思います!
皆様のアプリ制作のお役に立てると幸いです^^
開発環境
Ruby 3.2.3Ruby on Rails 7.1
gem devise
問題
LINE bot APIの実装中に、LINEのメッセージで送ったURLにリダイレクトすると、[ ログインしてください ]のバリデーションが発生しログインしなおしたら、リダイレクトしたかったページに飛べないという問題が発生しました。原因
ログイン後のリダイレクト先をroot_pathに設定していたため。解決方法
application_controllerに以下を記述。class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
def authenticate_user!
if user_signed_in?
super
else
session[:user_return_to] = request.fullpath
redirect_to new_user_session_path, :notice => 'ログインしてください。'
end
end
private
def after_sign_in_path_for(resource)
session[:user_return_to] || root_path
end
end
上から解説していくと、
・protect_from_forgery with: :exception
CSRF攻撃からアプリケーションを保護します。これは、ユーザーが認証済みのセッションを持っている場合に、そのセッションを悪用する攻撃を防ぎます。
・before_action :configure_permitted_parameters, if: :devise_controller?
Deviseコントローラが使用される場合に、configure_permitted_parametersメソッドを実行します。このメソッドは、通常、ストロングパラメータの設定を行うために使用されます。
・authenticate_user!
ユーザーがログインしているかどうかを確認します。ログインしていない場合、ログインページにリダイレクトし、フラッシュメッセージを表示します。また、ユーザーがログインしようとしていたページのURLをセッションに保存します。
・after_sign_in_path_for(resource)
ユーザーがログインした後にリダイレクトするパスを定義します。ユーザーがログインしようとしていたページがあればそこに、なければルートパスにリダイレクトします。
authenticate_user!メソッド内でsession[:user_return_to] = request.fullpathと設定しているため、ログイン前にアクセスしようとしたURL(パラメータ付きでも可)がセッションに保存されます。
そして、ログイン後にafter_sign_in_path_for(resource)メソッドが呼び出され、ここでsession[:user_return_to]の値が存在すればそのURLにリダイレクトします。これにより、ログイン前にアクセスしようとしたURL(パラメータ付きでも)に正しくリダイレクトし、パラメータの値も保持されます。
結論
私の実装ではLINEのアカウントIDを取得するために、LINEbotがLINEメッセージ内で送信したURLにパラメータもつけてリダイレクトするようにしていたのですが、authenticate_user!メソッドでログイン必須になるのでこの情報が失われてしまっていました。ですが上記の記述を行ったことにより、リダイレクト先の指定とパラメータの保持が行われることで、それらの情報を保持したままログインすることに成功しました!
参考になれば幸いです。