Laravel 5.6 - 会话过期后不再保留

Laravel 5.6 - Session is not persisting after it expires

我的两个本地环境有一个非常奇怪的问题。一旦我的会话由于太长时间没有刷新而过期,将按预期创建一个新会话。但是,如果我在 public 站点(不受 Auth 保护)上浏览,会话将不会持续存在,并且对于每个 get/post 请求,它将被忽略并创建一个新的(我可以在 storage/framework).

中看到 XRSF 令牌和正在创建的新文件

以下是几种情况:

  1. 如果没有用户登录,一切正常。

  2. 如果管理员用户已登录(选中 "Remember me"),但 public 用户未登录,则访问任何 public(未受保护的)路由(这使用默认 web 中间件)将如上所述重新创建会话。但是,一旦我访问 admin 中间件(web 中间件 + 验证检查)下的任何路由,会话将保持不变,之后 public 路由的问题就消失了。

  3. 如果两个用户都已登录并且我访问任何受保护的路由,会话会立即保持。

我尝试了以下方法,但没有成功:

解决问题的方法:

我重现问题的环境:

  1. 我的电脑

    • Windows 10 Pro x64,内部版本 1709
    • PHP7.2.0 (XAMPP)
  2. 我的笔记本电脑

    • Windows 10 Pro x64,内部版本 1803
    • PHP7.2.7 (XAMPP)
  3. 同事的笔记本电脑

    • macOS High Sierra 10.13.6
    • PHP 7.2.1 (MAMP)

可能不会导致问题的原因:

可能导致问题的原因:


以下是一些可能对您有用的文件:

.env

APP_NAME=MySite
APP_ENV=local
APP_KEY=base64:dEoI03jGqlhIZS4om6sx7j7aFMmKEweJpN72PijsCTQ=
APP_DEBUG=true
APP_URL=http://mySite

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=mySite
DB_USERNAME=root
DB_PASSWORD=password

BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
SESSION_LIFETIME=120
QUEUE_DRIVER=sync

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

RouteServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;

class RouteServiceProvider extends ServiceProvider
{
    /**
     * This namespace is applied to your controller routes.
     *
     * In addition, it is set as the URL generator's root namespace.
     *
     * @var string
     */
    protected $namespace = 'App\Http\Controllers';

    /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @return void
     */
    public function boot()
    {
        //

        parent::boot();
    }

    /**
     * Define the routes for the application.
     *
     * @return void
     */
    public function map()
    {
        $this->mapApiRoutes();

        $this->mapPublicRoutes();

        $this->mapOrganizationRoutes();

        $this->mapVolunteerRoutes();

        $this->mapAdminRoutes();
    }

    /**
     * Define the "web" routes for the application.
     *
     * These routes all receive session state, CSRF protection, etc.
     *
     * @return void
     */
    protected function mapAdminRoutes()
    {
        Route::middleware('admin')
             ->prefix("admin")
             ->namespace($this->namespace."\Admin")
             ->group(base_path('routes/admin.php'));
    }

    /**
     * Define the "web" routes for the application.
     *
     * These routes all receive session state, CSRF protection, etc.
     *
     * @return void
     */
    protected function mapPublicRoutes()
    {
        Route::middleware('web')
             ->namespace($this->namespace)
             ->group(base_path('routes/public.php'));
    }

    /**
     * Define the "organization" routes for the application.
     *
     * These routes all receive session state, CSRF protection, etc.
     * It also contains auth protection and nav builder
     *
     * @return void
     */
    protected function mapOrganizationRoutes()
    {
        Route::middleware('organization')
             ->prefix("organization")
             ->namespace($this->namespace . "\Organization")
             ->group(base_path('routes/organization.php'));
    }

    /**
     * Define the "volunteer" routes for the application.
     *
     * These routes all receive session state, CSRF protection, etc.
     * It also contains auth protection and nav builder
     *
     * @return void
     */
    protected function mapVolunteerRoutes()
    {
        Route::middleware('volunteer')
             ->prefix("volunteer")
             ->namespace($this->namespace . "\Volunteer")
             ->group(base_path('routes/volunteer.php'));
    }

    /**
     * Define the "api" routes for the application.
     *
     * These routes are typically stateless.
     *
     * @return void
     */
    protected function mapApiRoutes()
    {
        Route::prefix('api')
             ->middleware('api')
             ->namespace($this->namespace)
             ->group(base_path('routes/api.php'));
    }
}

routes/public.php

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register public routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', "LandingController@getIndex");

Route::group(["prefix" => "/auth"], function () {

    Route::get('/logout/{guard}', 'Common\AuthController@getLogout')->name('logout.get');

    Route::get('/login', 'Common\AuthController@getLogin')->name('login.get');
    Route::post('/login', 'Common\AuthController@postLogin')->name('login.post');

    Route::get('/register/{guard}', 'Common\RegistrationController@getRegister')->name('register.get');
    Route::post('/register/{guard}', 'Common\RegistrationController@postRegister')->name('register.post');

    Route::get("/register/success/{guard}", "Common\RegistrationController@getSuccess")->name("register.success.get");

});

Route::group(["prefix" => "admin/auth"], function() {

    Route::get("/login", "Admin\AuthController@getLogin")->name("admin.auth.login.get");
    Route::post("/login", "Admin\AuthController@postLogin")->name("admin.auth.login.post");

    Route::get("/logout", "Admin\AuthController@getLogout")->name("admin.auth.logout.get");

});

routes/admin.php

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "admin" middleware group. Routes are prefixed with "/admin"
| Now create something great!
|
*/

Route::get("/", "DashboardController@getIndex")->name("admin.dashboard");

// rest omitted

Http/Kernel.php

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        \App\Http\Middleware\TrustProxies::class,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],

        'admin' => [
            'web',
            'auth:admin',
            'nav:admin', // nav is custom middleware for loading navigation config to nwidart/laravel-menus library
        ],

        'organization' => [
            'web',
            'auth:organization',
            'nav:organization',
        ],

        'volunteer' => [
            'web',
            'auth:volunteer',
            'nav:volunteer',
        ],
    ];

    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        //'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'auth' => \App\Http\Middleware\AuthMiddleware::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'nav' => \App\Http\Middleware\NavigationBuilder::class,
    ];
}

AuthMiddlware.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class AuthMiddleware {
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard) {
        if (!Auth::guard($guard)->check()) {
            return redirect()->route(config("auth.guards.$guard.redirect"));
        }

        return $next($request);
    }
}

为了结束这个,我想说欢迎任何建议或评论。我需要确定这是否是我的本地问题,或者这是否与 Laravel 有关,以便我可以在他们的 GitHub 页面上打开一个问题。

经过进一步调查,我发现问题是由barryvdh/laravel-debugbar包引起的。通过删除它或将应用程序变成 production/debug=false,一切都按预期工作。一旦收到 barryvdh 的回复,我将更新此答案。