Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I fix a Safari 16.4 session bug that resets the session token randomly?

The latest update to Safari v16.4 (MacOS) is not maintaining a session in a Laravel (PHP) application I maintain and it will randomly logout users and not maintain items in the shopping cart.

This is reported in the Apple developer forum - https://developer.apple.com/forums/thread/728137 and there's a Webkit bug report here - https://bugs.webkit.org/show_bug.cgi?id=255524, but there is no resolution that I am aware of.

One possible workaround noted in the Webkit ticket is to change the SameSite attribute from 'lax' to 'none,' which fixes the issues on Safari, but breaks the session behavior on the latest version of Chrome and is generally not recommended.

Is there another approach to how we are handling our sessions or cookies that could resolve this issue, or is this truly a Webkit bug that can't be worked around until the issue is resolved with a Safari update?

like image 959
Bob. Avatar asked Oct 14 '25 09:10

Bob.


2 Answers

While this is not ideal, you can configure SameSite to target only buggy Safari implementations:

First override the built-in StartSession middleware.

namespace App\Http\Middleware;

use Illuminate\Session\Middleware\StartSession as FrameworkStartSession;

class StartSession extends FrameworkStartSession {
    protected function addCookieToResponse(Response $response, Session $session)
    {
        // Maybe use something a bit more sophisticated here like e.g. detecting only the buggy versions
        if (Str::contains(request()->server('HTTP_USER_AGENT'), 'Safari')) { 
           config([ 'session.same_site' => 'none' ]);
        }
        return parent::addCookieToResponse($response, $session);
    }
}

Then in your app/Http/Kernel.php replace the StartSession middleware under web with your own override.

This should leave other browsers to behave as before.

You can put the same logic in a service provider as well but that will not work if you are using Laravel Octane. Middleware should work in all cases.

like image 66
apokryfos Avatar answered Oct 16 '25 21:10

apokryfos


I resolved by referencing above your code first this does not check for other browsers so I update your code a little bit as below. Here are updated version. Inside CustomSession.php

<?php

namespace App\Http\Middleware;

use Illuminate\Contracts\Session\Session;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Support\Str;
use Illuminate\Session\Middleware\StartSession as FrameworkStartSession;

class CustomSession extends FrameworkStartSession {
    protected function addCookieToResponse(Response $response, Session $session)
    {
        // Maybe use something a bit more sophisticated here like e.g. detecting only the buggy versions
        $userAgent = request()->server('HTTP_USER_AGENT');

        if (Str::contains($userAgent, 'Safari') && !Str::contains($userAgent, 'Chrome')) {
           config([ 'session.same_site' => 'none' ]);
        }
        else {
            // Configure session for other browsers
            config(['session.same_site' => 'lax']);
        }
        return parent::addCookieToResponse($response, $session);
    }
}


Here are configurations inside web Kernel.php from Laravel's default StartSession to CustomSession

 'web' => [
           .... 

           \Illuminate\Session\Middleware\StartSession::class,  

           ....
          ],
  

to

 'web' => [
            ...

           \App\Http\Middleware\CustomSession::class,

            .....
         ],


like image 29
Zaw Zaw Win Avatar answered Oct 16 '25 23:10

Zaw Zaw Win



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!