82383


**数日前に質問を投稿してから進展があり、当初記述しておりました内容とは論点（原因）が異なる事が分かりましたので、質問文全体を新しく編集し直しました。**

**[他のQ&Aサイト](https://teratail.com/questions/355888)でも質問しておりますが、回答が中々付かなかった為こちらでも質問させて頂きました。進捗が有りました際には両方にてアップデートしていきたいと考えております。**

### 背景

コードをいじっていないにも関わらず、実装出来ていたログイン機能が使えなくなりました。ログイン画面で正しいメールアドレス・パスワードを入力しても再度ログイン画面にリダイレクトされてしまうと言った状況です。  
尚、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**

[code]

    config.session_store :cookie_store, expire_after: 8.hours
    
[/code]

これらの作業が済んだ後、上記の問題が発生した次第です。

### 該当のソースコード

**routes.rb**

[code]

    get "login" => "users#login_form"
    post "login" => "users#login"
    post "logout" => "users#logout"
    
[/code]

**application_controller.rb**

[code]

    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
    
[/code]

**users_controller.rb**

[code]

    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  
    
[/code]

ログインに成功した場合は`redirect_to("/")`の様に、トップページに遷移するようにしています。

### ログ

ログインを試みた際のログです。  
`Started GET "/"`とある様に、ソースコード上ログインには成功しているようです。しかしその後`Filter chain halted as
:authenticate_user rendered or redirected`と怒られ、`"/login"`にリダイレクトされています。

[code]

    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)
    
[/code]

### Burp Suitでの表示

`ngrok`を使用し、外部からアクセスしてからログインした際の記録。  
左下の「Request」内に`Cookie`が、また右下の「Response」内に`Set-cookie`がそれぞれ表示されています。  
[![画像の説明をここに入力](https://i.stack.imgur.com/tEtB6.jpg)](https://i.stack.imgur.com/tEtB6.jpg)

ローカル環境でログインを試みた際の記録。  
左下の「Request」内に`Cookie`が、また右下の「Response」内に`Set-cookie`がそれぞれ出てきません。  
[![画像の説明をここに入力](https://i.stack.imgur.com/waEHr.jpg)](https://i.stack.imgur.com/waEHr.jpg)

### 試したこと

サーバーの再起動、パソコンの再起動を試しても状況は変わらず、  
ブラウザによる違い（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`内にて、以下の様にセッションの履歴を執拗に消す。

[code]

    def login_form
      reset_session
      session[:user_id] = nil
      session.delete(:user_id)
    end
    
[/code]

また外部から私のlocalhostに接続した場合はなぜか上手くいく為、直接localhostに接続した場合との違いを考えてみました。  
ローカル環境から直接localhostに接続した場合は、このようにURL横がビックリマークの表示になります。  
[![画像の説明をここに入力](https://i.stack.imgur.com/snKa4.png)](https://i.stack.imgur.com/snKa4.png)

一方で外部から私のlocalhostに接続した場合は鍵マークになっています。  
[![画像の説明をここに入力](https://i.stack.imgur.com/whc2q.png)](https://i.stack.imgur.com/whc2q.png)

ページがSSL化されているかどうかでセッションIDが付与されないなどの違いが出てくるものなのでしょうか…。


CC BY-SA 4.0
2021-08-24T08:08:44.203
81011
2021-09-09T14:42:47.210
2021-08-30T09:12:13.560
46737
46737
question
ruby-on-rails mysql cookie session sessionid
ローカル環境でのみ、ログインに成功してもセッションIDが付与されない。


ログを見る限りログインは成功してトップにリダイレクトまではできていて  
トップのコントローラ内のコードがまずくてエラーになってるだけに見えます

Processing by UsersController#login  
の中ではエラーはなく普通に  
Redirected to http://localhost:3000/  
でおわってます

Processing by UsersController#top  
の中でまず

[code]

    before_action :authenticate_user, {except: [:new, :create, :login_form, :login]}
    
[/code]

の except に top がはいってないので呼ばれます

その中の

[code]

    if @current_user == nil
          flash[:notice] = "You need to log in"
          redirect_to("/login")
    end
    
[/code]

でまた /login に戻されて  
以下 redirect の繰り返しになってるんじゃないですか？

> 尚、deviseは使用しておりません。

ということなのでデータベースの保存ロジックがオリジナルなのであれば  
ログインが成功してるのに @current_user がなぜ null なのかこれ以上回答側でわかることはありません

[code]

      def set_current_user
        @current_user = User.find_by(id: session[:user_id])
        pp '@current_user = ' + current_user
      end
    
      def authenticate_user
        pp '@current_user = ' + current_user
        if @current_user == nil
          flash[:notice] = "You need to log in"
          redirect_to("/login")
        end
      end
    
[/code]

とかデバッグ入れてみればなにかわかるかもですね

ちな質問とは無関係ですが Rails には  
@current_user == nil  
のかわりに  
@current_user.nil?  
というメソッドがあります


CC BY-SA 4.0
2021-08-29T18:12:18.223
81104
2021-08-29T18:12:18.223
81011
answer


無事解決致しました！  
config > initializers
内に「session_store.rb」と言うファイルを以前自分で作ってしまったのが原因でした。ファイルにはセッションに関する内容を記述しておりました。

[code]

    app_name = "アプリ名"
    Rails.application.config.session_store :cookie_store, key: "_アプリ名_session", expire_after: 8.hours, secure: true
    
[/code]

以前セッションについて自分でカスタマイズ出来ないかと考えてたことがあり（セッションはRailsのデフォルトでは1日で切れるようですが、それを8時間に設定したかった）、これを「session_store.rb」と言うファイル内で編集できると知りました。しかしどうやらRails5以降ではこのファイルがデフォルトで生成されないようでしたので、どうやって編集出来るのかを模索していた所、恐らく[こちらの様なページ](https://teratail.com/questions/239249)を参考にし、ファイルを自分で作成したのでした。

勝手にこの作業をしていた事を忘れておりました…。回答者さまが想像できない部分だったと思います。申し訳ありません。

`session_store.rb` は削除し、 `application.rb` にて一旦今回は以下を記述する事に致しました。

[code]

    config.session_store :cookie_store, secure: Rails.env.production?
    
[/code]


CC BY-SA 4.0
2021-09-09T14:42:47.210
82383
2021-09-09T14:42:47.210
46737
81011
answer