42440


laravelでリダイレクト処理をした際にセッションが保持されません。  
Laravel Framework 5.4.36 を利用しています。

以下のようなスクリプトを用意しました。

### test1.php

[code]

    class test1 extends Controller
    {
      public function index()
        {
            Session::put('key','value');
            Session::save();
            header("Location: /test2");
            exit;
        }
    }
    
[/code]

### test2.php

[code]

    class test2 extends Controller
    {
      public function index()
        {
            var_export(Session::all());
        }
    }
    
[/code]

コードにある通り  
test1.phpはセッションの保存とtest2へのリダイレクト処理  
test2.phpはセッションを表示する処理のスクリプトです。

ここから問題なのですが

  1. 初回アクセス時に **test1.php** → **test2.php** と表示すると  
セッションが保持されておらず、  
test1.php で putしたセッションが **表示されません** 。

  2. 一方で、初回アクセス時に **test2.php** を一旦表示した後、  
**test1.php** → **test2.php** と表示すると、  
test1.php で putしたセッションが **表示されます** 。

１のケースでもセッションを保持するためにはどのようにすればよいでしょうか？


CC BY-SA 3.0
2018-03-16T08:51:11.743
42437
2018-03-16T10:35:27.767
2020-06-17T08:14:45.997
-1
26236
question
php laravel laravel-5
laravelの初回リダイレクト時にセッションの値が保持されない


端的に言えば

[code]

        header("Location: /test2");
        exit;
    
[/code]

はLaravelにおいて書いてはいけないといっても過言ではない書き方です。少なくともController内で`exit`するのはやめましょう。(これがセッションの発行されない原因です。)

代わりに

[code]

        return redirect('/redirect/sample');
    
[/code]

のように書くことでセッションを伴ったリダイレクトが可能です。

とりあえず片方をコメントアウトしたものをサンプルとして用意したので、コメントを入替えながら`curl
-v`やCookieを消したブラウザ等で試していただければ違いがわかるとは思います。

[code]

    Route::get('/redirect/', function() {
        Session::put('key','value');
        Session::save();
    //    header("Location: /redirect/sample");
    //    exit;
        return redirect('/redirect/sample');
    });
    Route::get('/redirect/sample', function () {
        var_dump(Session::all());
    });
    
[/code]

* * *

## なぜ？

Laravel
では`\Illuminate\Session\Middleware\StartSession`というミドルウェアでセッションのCookieを発行していますが、実際にその発行を行っている部分は
[ここ](https://github.com/illuminate/session/blob/v5.6.12/Middleware/StartSession.php#L71)であり、Controllerの処理よりも後です。(Controllerや以降のミドルウェアは[その直前](https://github.com/illuminate/session/blob/v5.6.12/Middleware/StartSession.php#L63)で呼び出されています)

([Laravel 5 のタマネギ構造実装処理 - Web Application Security
Memo](https://www.pupha.net/archives/3032/) なども参照)

そのため、Controllerの途中でexitしてしまうとこのコードは実行されないためセッションのCookieは発行できないのです。


CC BY-SA 3.0
2018-03-16T10:35:27.767
42440
2018-03-16T10:35:27.767
2376
42437
answer