ycs77 / laravel-recover-session
Recover Laravel session when form post back from third-party API.
Fund package maintenance!
Patreon
Requires
- php: >=8.1
- illuminate/cache: >=9.0
- illuminate/config: >=9.0
- illuminate/contracts: >=9.0
- illuminate/encryption: >=9.0
- illuminate/http: >=9.0
- illuminate/session: >=9.0
- illuminate/support: >=9.0
- symfony/http-foundation: >=6.0
Requires (Dev)
- mockery/mockery: ^1.4
- orchestra/testbench: >=7.0
- pestphp/pest: ^2.6
README
Recover Laravel session when sending a form post request back from a third-party API like NewebPay.
Currently, Laravel's default Cookie SameSite value is set to Lax
. This setting prevents cookies from being sent when using form post requests to transmit data to websites on other domains. Consequently, after completing a payment and being redirected back to the original website, users may appear to be automatically logged out due to the inability to retrieve the original login cookie. This package addresses and resolves this issue.
Installation
Via Composer:
composer require ycs77/laravel-recover-session
Publish config:
php artisan vendor:publish --tag=recover-session-config
Usage
Now you need to call RecoverSession::preserve()
to save the current session ID into the cache and include the key in your callback URL. This allows the current session to be resumed after the API returns with the key:
use Ycs77\LaravelRecoverSession\Facades\RecoverSession; public function pay(Request $request) { $key = RecoverSession::preserve($request); ThirdPartyApi::callbackUrl('/pay/callback?sid='.$key); // send post form request to the third-party API... }
This package will automatically retrieve the encrypted session ID from the callback URL and restore the original session state upon returning to the site.
Reference details for the SameSite: https://developers.google.com/search/blog/2020/01/get-ready-for-new-samesitenone-secure
Manually Register Middleware
If you are not using the global recover session, you can set the config recover-session.global
to false
, and adjust the order of the middleware so that RecoverSession
is placed below StartSession
. by default, Laravel's Kernel
does not include the $middlewarePriority
property, so you need to add it manually.
If you are using Laravel 9 or 10, you should add the $middlewarePriority
property in your application's app/Http/Kernel.php
file:
class Kernel extends HttpKernel { /** * The priority-sorted list of middleware. * * Forces non-global middleware to always be in the given order. * * @var string[] */ protected $middlewarePriority = [ \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class, \Illuminate\Cookie\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Ycs77\LaravelRecoverSession\Middleware\RecoverSession::class, // need to place `RecoverSession` below `StartSession` \Illuminate\View\Middleware\ShareErrorsFromSession::class, \Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class, \Illuminate\Routing\Middleware\ThrottleRequests::class, \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class, \Illuminate\Contracts\Session\Middleware\AuthenticatesSessions::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, \Illuminate\Auth\Middleware\Authorize::class, ]; }
If you are using Laravel 11+, you can add the RecoverSession
middleware to the $middlewarePriority
property in the app/Http/Kernel.php
file:
->withMiddleware(function (Middleware $middleware) { $middleware->priority([ \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class, \Illuminate\Cookie\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Ycs77\LaravelRecoverSession\Middleware\RecoverSession::class, // need to place `RecoverSession` below `StartSession` \Illuminate\View\Middleware\ShareErrorsFromSession::class, \Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class, \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, \Illuminate\Routing\Middleware\ThrottleRequests::class, \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, \Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class, \Illuminate\Auth\Middleware\Authorize::class, ]); })
If you are using Laravel 11.31+, it provides a concise method to append middleware to the priority list:
->withMiddleware(function (Middleware $middleware) { $middleware->appendToPriorityList( \Ycs77\LaravelRecoverSession\Middleware\RecoverSession::class, \Illuminate\Routing\Middleware\ValidateSignature::class ); })
Final, you can add the RecoverSession
middleware to the callback route for the API:
use Ycs77\LaravelRecoverSession\Middleware\RecoverSession; Route::post('/pay/callback', [PaymentController::class, 'callback']) ->middleware(RecoverSession::class);
Sponsor
If you think this package has helped you, please consider Becoming a sponsor to support my work~ and your avatar will be visible on my major projects.