I have a very weird issue with my two of my local environments. Once my session expires due to not being refreshed for too long, a new session will be created as expected. However, if I am browsing on public site (which is not under Auth protection), the session will not persist and with each get/post request, it will be ignored and a new one will be created (I can see that on XRSF token and new file being created in storage/framework).
Here are few scenarios:
-
If no user is logged in, everything works fine.
-
If admin user is logged in, but public user is not, accessing any public (unprotected) route (which uses default "web" middleware) will recreate session as described above. However, once I access any route under "admin" middlware ("web" middleware + auth check), session will stick and after that, the issue for public route disappears.
-
If both users are logged in and I access any protected route, session sticks immediately.
I tried the following, without any success:
- reading and trying out suggestions from other threads
- remove all caches
- reinstalled XAMPP
- tried different browsers (same result for Chrome, Edge and freshly installed Firefox)
- setting SESSION_DOMAIN - this actually broke Edge, sessions stopped working altogether
- removed site cookies
- changed APP_URL and APP_NAME
- tried file and database drivers for session
- accessed site using XAMPP through VHost (e.g. http://mySite/) and through php artisan server
What resolves the issue:
- accessing protected page
- deleting cookies
- reopening browser
Environments where I reproduced the issue:
-
My PC
- Windows 10 Pro x64, build 1709
- PHP 7.2.0
-
My laptop
- Windows 10 Pro x64, build 1803
- PHP 7.2.7
The issue was not reproduced on colleague's macOS running MAMP with PHP 7.2.
What probably does not cause the issue:
- file permissions
- my Laravel configuration (as I tried dozen of suggestions in similar threads)
- XAMPP installation
What might caused the issue:
- cookies (although I have no idea how)
- PHP settings
- Laravel (given the weird behavior in given scenarios, I cannot exclude this option yet)
- Windows
Here are some files that might be useful for you:
.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);
}
}
To end this, I would like to say that any suggestion or comment is welcomed. I need to determine if this is my local issue, or if this has something to do with Laravel so that I can open an issue on their GitHub page.
via Chebli Mohamed
Aucun commentaire:
Enregistrer un commentaire