Laravel 8 session token lost after redirect to external URL

35 Views Asked by At

I have a Laravel 8 website in which users fill in a form and click a link to take them to an external payment website. Once the user has paid (or canceled payment), the payment website redirects the user to my site. For about 30% of users, the browser cookie storing the laravel_session cookie is not included in the headers and the user is logged out of my website. According to Apache logs, The browser/platform is not a consistent factor in whether the user's cookie disappears or not.

The payment site is calling my url with HTTPS. HTTPS is forced on by Apache config, so I am sure that all users are starting off from the same domain they are being returned to. Perhaps the only smidgen of doubt I have is that some users are using an old URL that redirects to the new URL using an .htaccess directive. When I go to the old URL, I see the new URL in the browser's address bar, matching the redirect address in the payment site, so I do think that is all working normally.

When the user submits the form, it brings them to a controller method that does this:

public function saveForm(Request $request) {
<snip>
$temp = call_user_func([new $controllerClass, $function], $request);
$sessionCookie = Cookie::get(config('session.cookie'));
logger()->info('Session Cookie Value: ' . $sessionCookie); //always returns a proper value
return $temp;
}

Note that I am not calling a route here, and no route is defined for $function, so I don't expect any middleware to kick on the call to $function.

The $function in question makes a curl call to the payment website for a token. Upon success, I log the session value again for debugging, and redirect like this. Note that I am not making any changes to the cookie before redirecting. :

$sessionCookie = Cookie::get(config('session.cookie'));
logger()->info('Session Cookie Value: ' . $sessionCookie); //always returns a proper value
return redirect()->away($url);

I am returning up the chain without using die or dd or anything that would kill execution.

I believe my middleware is pretty out-of-the-box:

  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,
            \App\Http\Middleware\SetLocale::class,
        ],
        'api' => [
            'throttle:60,1',
            'bindings',
        ],
   ];

   protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
   ];

My route for receiving the redirection from the payment site is under 'web':

Route::post('pay/accepted', [PayController::class, 'accepted'])->name('pay.accepted');

Session.php values:

'driver' => env('SESSION_DRIVER', 'file'),
'lifetime' => 120,
'expire_on_close' => true,
'encrypt' => false,
'files' => storage_path('framework/sessions'),
'connection' => null,
 'table' => 'sessions',
'lottery' => [2, 100],
'cookie' => 'laravel_session',
'path' => '/',
'domain' => null,
'secure' => env('SESSION_SECURE_COOKIE', null),

When the payment site redirects to mine, the first indication that something is wrong is that EncryptCookies::handle does not see a cookie in the headers. Inside Authenticate::handle, Auth::check() is false and the user is redirected to auth/login. Again, this only happens about 30% of the time, making it difficult to debug properly.

I'd be very grateful for any ideas on how to debug further.

0

There are 0 best solutions below