数日前に質問を投稿してから進展があり、当初記述しておりました内容とは論点(原因)が異なる事が分かりましたので、質問文全体を新しく編集し直しました。
背景
コードをいじっていないにも関わらず、実装出来ていたログイン機能が使えなくなりました。ログイン画面で正しいメールアドレス・パスワードを入力しても再度ログイン画面にリダイレクトされてしまうと言った状況です。
尚、deviseは使用しておりません。
ログイン周りのコードに問題があるのかとまず考えましたが、ログを辿るとログインが成功した際のコードに分岐されている事が分かりました。
またBurp Suite
と言う「ブラウザ - サーバー間(ローカルプロキシ)」の通信の記録を観察するツールを使用し調べてみた所、ログイン後にセッションIDがなぜか付与されておらず、結果としてauthenticate_user
に引っ掛かりログインが出来なくなっている状況だと分かりました。この原因を突き止め、解決したいです。
更にngrok
と言う、localhost
にhogehoge.ngrok.comで外部からアクセスできるツールを使い、外部からアクセスした場合に違いが生じるかを確認した所、何とこちらではログインに成功しました。その様子を同じようにBurp Suite
で調べた所、こちらではログイン後にセッションIDが付与されている様子が確認出来ました。
つまりローカル環境でログインを試みた際にのみ、なぜかセッションIDが付与されなくなっているようなのです。
直近でコードに関して作業はしておらず、以下の作業をしておりました。
- Gitの導入。
- 作成した「アプリ1」を、Gitを使用しGitHubにプッシュ。
- Sourcetreeを導入し、GitHubにプッシュ出来るよう連携。
- GitHubの内容をSourcetreeでクローン。フォルダ名を「アプリ2」とし、Sourcetree内で連携させたいローカルのワークツリーに指定。
更に前に作業していた事はと言えば、セッションに関して以下の1行加えた事くらいです。
またこの行は現在コメントアウトしておりますが、状況は変わりません。
application.rb
config.session_store :cookie_store, expire_after: 8.hours
これらの作業が済んだ後、上記の問題が発生した次第です。
該当のソースコード
routes.rb
get "login" => "users#login_form" post "login" => "users#login" post "logout" => "users#logout"
application_controller.rb
class ApplicationController < ActionController::Base protect_from_forgery with: :null_session before_action :set_current_user skip_before_action :verify_authenticity_token caches_action :set_current_user, :authenticate_user, :forbid_login_user def set_current_user @current_user = User.find_by(id: session[:user_id]) end def authenticate_user if @current_user == nil flash[:notice] = "You need to log in" redirect_to("/login") end end def forbid_login_user if @current_user flash[:notice] = "You are already logged in" redirect_to("/") end end end
users_controller.rb
before_action :authenticate_user, {except: [:new, :create, :login_form, :login]} before_action :forbid_login_user, {only: [:new, :create, :login_form, :login]} before_action :ensure_correct_user, {only: [:edit, :update]} before_action :ensure_correct_user_account, {only: [:setting_password, :update_password, :setting_email, :update_email, :delete_account, :destroy]} caches_action :index, :show, :follow, :new, :create, :edit, :user_params, :update, :destroy, :login_form, :login, :logout, :likes, :ensure_correct_user, :followings, :followers, :top def login @user = User.find_by(email: params[:email]) if @user && @user.authenticate(params[:password]) session[:user_id] = @user.id flash[:notice] = "You have successfully logged in" redirect_to("/") else @error_message = "Email address or password is incorrect" @email = params[:email] @password = params[:password] render("users/login_form") end end def login_form end def logout session[:user_id] = nil flash[:notice] = "You have successfully logged out" redirect_to("/login") end
ログインに成功した場合はredirect_to("/")
の様に、トップページに遷移するようにしています。
ログ
ログインを試みた際のログです。
Started GET "/"
とある様に、ソースコード上ログインには成功しているようです。しかしその後Filter chain halted as :authenticate_user rendered or redirected
と怒られ、"/login"
にリダイレクトされています。
Started POST "/login" for ::1 at 2021-08-24 14:44:31 +0900 Processing by UsersController#login as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"JBcKtTsdCT0JXgyIfzjKVqi/8KEz4pRmUXB2Kybn8eHcnz7UKXoMsbBRkBCnoUqwnIdi4hUkZ/6oQKFVqMyG/g==", "email"=>"hoge", "password"=>"[FILTERED]"} User Load (35.1ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IS NULL LIMIT 1 ↳ app/controllers/application_controller.rb:9 User Load (0.6ms) SELECT `users`.* FROM `users` WHERE `users`.`email` = 'hoge' LIMIT 1 ↳ app/controllers/users_controller.rb:255 Redirected to http://localhost:3000/ Completed 302 Found in 422ms (ActiveRecord: 41.9ms) Started GET "/" for ::1 at 2021-08-24 14:44:32 +0900 Processing by UsersController#top as HTML User Load (0.6ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IS NULL LIMIT 1 ↳ app/controllers/application_controller.rb:9 Redirected to http://localhost:3000/login Filter chain halted as :authenticate_user rendered or redirected Completed 302 Found in 6ms (ActiveRecord: 0.6ms) Started GET "/login" for ::1 at 2021-08-24 14:44:32 +0900 Processing by UsersController#login_form as HTML User Load (0.5ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IS NULL LIMIT 1 ↳ app/controllers/application_controller.rb:9 Rendering users/login_form.html.erb within layouts/application Rendered users/login_form.html.erb within layouts/application (0.9ms) CACHE User Load (0.1ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IS NULL LIMIT 1 ↳ app/views/layouts/application.html.erb:51 Completed 200 OK in 244ms (Views: 233.9ms | ActiveRecord: 0.5ms)
Burp Suitでの表示
ngrok
を使用し、外部からアクセスしてからログインした際の記録。
左下の「Request」内にCookie
が、また右下の「Response」内にSet-cookie
がそれぞれ表示されています。
ローカル環境でログインを試みた際の記録。
左下の「Request」内にCookie
が、また右下の「Response」内にSet-cookie
がそれぞれ出てきません。
試したこと
サーバーの再起動、パソコンの再起動を試しても状況は変わらず、
ブラウザによる違い(Google Chrome, Firefox, Braveで試しました)も関係ありませんでした。
サーバーやセッション関連に原因があるかもしれず、プログラミング関連の質問としてそぐわなくなっておりましたら申し訳ありません。どなたかご助言を頂けますと有難いです。
補足情報(FW/ツールのバージョンなど)
ruby 2.6.4p104
RubyGems 3.0.3
Rails 5.2.3
Burp Suite Community Edition 2021.8.2
追記
以下の作業を試みましたが、依然として結果は同じでした。
rails s
をする際のポートを3000から3001に変える。- コマンドにて
bundle exec rake tmp:cache:clear
を実行。 - コマンドにて
rails tmp:clear
を実行。 users_controller.rb
のlogin_form
内にて、以下の様にセッションの履歴を執拗に消す。
def login_form reset_session session[:user_id] = nil session.delete(:user_id) end
また外部から私のlocalhostに接続した場合はなぜか上手くいく為、直接localhostに接続した場合との違いを考えてみました。
ローカル環境から直接localhostに接続した場合は、このようにURL横がビックリマークの表示になります。
一方で外部から私のlocalhostに接続した場合は鍵マークになっています。
ページがSSL化されているかどうかでセッションIDが付与されないなどの違いが出てくるものなのでしょうか…。
回答1件
あなたの回答
tips
プレビュー