Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

LaravelでフォームデータをPOST送信しても中身が空になってしまいます。他にも不可解な現象があります。助けてください。

前提

プログラミング3か月程度の初学者です。
知識が浅く、拙い説明になりますがお許しください。
Docker上にLaravel8系でwebアプリ開発を学習しています。

学習の途中でLaravel Broadcastによる非同期のチャット機能を実装しました。
Vueコンポーネントでaxiosを使ってLaravelと通信するという仕組みです。
この時参考にした記事ではapi.phpにルーティングを定義することになっていたので、そのようにしていました。
この機能は問題なく実装出来ました。

その後、Vueを使ってページをリロードせずに表示内容を変える、ということに味を占めて、いいね機能やリスト表示にもvueコンポーネントを使った機能を実装しました。
これらも問題なく動作しました。

ところが、開発を始めてからずっと触っていなかったログアウトをしてみたところ、
Session store not set on requestというエラーが出るようになりました。
ネットで調べた方法をいろいろ試しましたが、解決しなかったので後回しにすることにしました。

その間、axiosを使う場合でもweb.phpにルーティングを定義するという情報があったのでapi.phpに定義したものをweb.phpに移し、axiosに指定したurlもweb用に変えました。(apiとwebの根本的な違いが分かっていません。ごめんなさい。)
それでも問題なく機能しました。

そして、お問い合わせフォームを送信する機能を実装していた時に、コントローラーで受け取ったリクエストをloggerでデバックしてみたところarray()と中身が入っていませんでした。
urlを変えてみたり、ルートを定義するファイルを変えてみたり、いろいろ試しましたが一向に改善しません。

あらすじが長くなり、しかもよくわからない説明かもしれませんが、全く糸口が見えず自力で解決出来そうにないのでお力添え頂きたいです。

解決したいこと

・ログアウト出来るようになりたい。
・フォーム送信できるようになりたい・
・この一連の問題はなぜ起こっているのか知りたい。

発生している問題・エラー

ログアウト出来ない問題について

認証機能はLaravel Breezeを使っています。

web.php
require __DIR__.'/auth.php'; //ここでログアウトのルートを指定してると思います

Route::get('/', [HomeController::class, 'index'])->name('top');

Route::get('/signup', [UserController::class, 'add'])->name('signup');
Route::post('/users/create', [UserController::class, 'create']);

Route::get('/contacts', [HomeController::class, 'showContactForm']);  //お問い合わせ機能へのルーティングはここ
Route::post('/contacts', [HomeController::class, 'receiveContact']);

Route::middleware(['auth'])->group(function() {
  Route::get('/users', [UserController::class, 'index'])->name('mypage');
  Route::get('/users/edit', [UserController::class, 'edit'])->name('user-edit');
  Route::post('/users/update', [UserController::class, 'update'])->name('user-update');
  Route::delete('/users/delete', [UserController::class, 'delete']);

  Route::get('/reviews/school/{school_id}', [ReviewController::class, 'showList']);
  Route::get('/reviews/review/{id}', [ReviewController::class, 'showReview']);
  Route::get('/reviews', [ReviewController::class, 'add']);
  Route::post('/reviews/create', [ReviewController::class, 'create']);
  Route::delete('/reviews/delete', [ReviewController::class, 'delete']);


  Route::get('/reviews', function() {
    return \App\Models\Message::all();
  });

  Route::post('/reviews/message', function() {
    $message = \App\Models\Message::create(['user_id' => Auth::id(), 'review_id' => request()->reviewId, 'message' => request()->message]);

    event((new MessageSent($message))->dontBroadcastToCurrentUser());

    return $message;
  });


  Route::get('/schools/{id}', [SchoolController::class, 'showSchool'])->name('school');

  Route::get('/rankings', [RankingController::class, 'index'])->name('ranking');
  Route::post('/rankings', [RankingController::class, 'showRanking']);

  Route::get('/follow/{id}', [FollowController::class, 'getCurrentStatus']);
  Route::post('/follow', [FollowController::class, 'switchFollow']);

  Route::get('/like/{id}', [LikeController::class, 'current']);
  Route::post('/like', [LikeController::class, 'switchLike']);

  Route::get('/password/change', [ChangePasswordController::class, 'showChangePasswordView']);
  Route::post('/password', [ChangePasswordController::class, 'changePassword']);

  Route::get('/email/edit', [ChangeEmailController::class, 'showChangeEmailForm']);
  Route::post('/email', [ChangeEmailController::class, 'sendChangeEmailLink'])->name('email');
  Route::post('/email/reset', [ChangeEmailController::class, 'reset']);
});

ログアウト機能はauth.phpにルーティングが定義され、AuthenticatedSessionControllerのdestroyアクションで実行されています。

最初に定義されているrequire __DIR__.'/auth.php';のコードは、当初ファイルの最後に書かれていました。
その状態でログアウトすると、

Session store not set on requestというエラーが出ます。

その後一番上に移動したら、419エラーに変わりました。

auth.php
use App\Http\Controllers\Auth\AuthenticatedSessionController;
use App\Http\Controllers\Auth\ConfirmablePasswordController;
use App\Http\Controllers\Auth\EmailVerificationNotificationController;
use App\Http\Controllers\Auth\EmailVerificationPromptController;
use App\Http\Controllers\Auth\NewPasswordController;
use App\Http\Controllers\Auth\PasswordResetLinkController;
use App\Http\Controllers\Auth\RegisteredUserController;
use App\Http\Controllers\Auth\VerifyEmailController;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\HomeController;

//省略

Route::post('/logout', [AuthenticatedSessionController::class, 'destroy'])
                ->middleware('auth')
                ->name('logout');     //これがログアウトのルーティング
AuthenticatedSessionController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class AuthenticatedSessionController extends Controller
{
    //省略

    /**
     * Destroy an authenticated session.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function destroy(Request $request)
    {
        Auth::logout();

        $request->session()->invalidate();

        $request->session()->regenerateToken();

        return redirect('/');
    }
}

一応api.phpも載せておきます。

api.php
<?php

use App\Repositories\ReviewRepository;
use App\Events\MessageSent;
use App\Http\Controllers\LikeController;
use App\Http\Controllers\ReviewController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Auth;


Route::middleware('auth:api')->get('/user', function (Request $request) {    //これは最初からありました。
    return $request->user();
});

自分で試したこと

Kernel.php
protected $middleware = [
        //ここから
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    //ここまでを追加してみました。
        // \App\Http\Middleware\TrustHosts::class,
        \App\Http\Middleware\TrustProxies::class,
        \Fruitcake\Cors\HandleCors::class,
        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

web.phprequire __DIR__.'/auth.php';が最後にある状態で、
kernel.phpにミドルウェアを追加してみました。
するとSession store not set on request419エラーに変わりましたが、解決にはならなかったので元に戻しました。

何が原因でこのような事態になっているのか見当すらつきません。
自力で解決策を探るのは限界を感じます。
どうかお力添えください。お願いします。

0

1Answer

419エラーはcsrf_tokenがexpireしただからです。

ページをリフレッシュすればログアウトはできるはずです。

0Like

Comments

  1. ご回答ありがとうございます。

    「csrf_tokenがexpireした」というのはセッションの有効期限が切れたという意味でしょうか?
    確かにログアウトした後、エラー画面が表示されて、ページをリロードするとログアウト処理は出来ています。
    しかしログイン直後にログアウトしてもエラーが表示されます。

    config/session.phpのlifetimeは120に設定されているので、セッションの有効期限が切れたということではないと思うのですが、間違った理解をしていたら申し訳ありません。

    また、csrfトークンはセッションの"_token"というキーの値だと認識していますが、httpリクエストをlogにデバッグすると、ログアウトの際もこの値は保持されています。

    大変知識不足で、至らぬ点がありましたら申し訳ありません。

Your answer might help someone💌