Right now the session data for anonymous (non-authenticated) users of my web application is not moved/assigned to the user once they log in or register.
For example: An anonymous user interacts with the application, creates some session data (say products in a shopping cart), then logs in/registers and then logs out, the session data is still accessible and is not moved/made inaccessible to the now unauthenticated user.
I am using file session driver (no database), perhaps someone could provide some example of what needs to be changed (I presume in Session config) in order to make any session data created by an anonymous user become assigned to and only accessible by this user once they authenticate by logging in or registering and only while the user is authenticated.
The requirement for this is because users of the application create unique objects (tied to their user_id) which are only persisted after payment when order processing runs. I store them in session until the user logs-in/registers and goes through with the final order step and only then are they persisted. So I absolutely can't have user specific objects retained in non-authenticated sessions after the user logs out. I could flush the session on logout, but ideally I want to keep them for when the user logs back in.
The authentication system just uses the session as storage to persist authentication state across requests. However, Laravel's authentication system is not responsible for handling all your session data, it only cares about storing authentication related information, such as user details. If you want to handle additional session data for authenticated users, you need to do that manually.
The logic is simple:
If a user does some action like adding something to a shopping cart, the data stays there as the session is bound via cookies to the browser from which the requests are coming from.
If a user logs in from that same browser, Laravel's authentication system checks the credentials and if they are correct it stores the necessary information about that user in the same session. The previously stored data about the shopping cart is still there and untouched, so you can use it in the context of the logged in user. If at this point you want to persists the session cart so it's available for the user when he accesses his/hers account in the future, then you need to store the details in the database. Below are a few steps showcasing a way to achieve that:
1. Create an event listener, let's name it SyncShoppingCart
, that will listen to the Illuminate\Auth\Events\Login
event (the double backslashes in the command \\
are needed to escape a single slash):
php artisan make:listener SyncShoppingCart --event=Illuminate\\Auth\\Events\\Login
2. The previous command created a file in app/Listeners
named SyncShoppingCart.php
. Now you just need to stores the cart data in the user's in the handle
method of that class. The example below assumes you have cart_item
table that stores informations about items added to the cart, and you have a CartItem
model defined for it. This example is simplified and you will need to modify it to suit your needs, but it's a good starting point for understanding this approach:
public function handle(Login $event)
{
// Iterate over the session cart items and
foreach (session()->get('cart') as $item) {
$cartItem = new App\CartItem();
// Set the user ID for the cart item so you know
// which user added this item to the cart
$cartItem->user_id = Auth::id();
// Set the product ID and any other properties
// you want stored for the cart item
$cartItem = $item->product_id;
// ...
// Save the cart item to the database
$cartItem->save();
}
session()->forget('cart');
}
3. Then register the even listener in the app/Providers/EventServiceProvider.php
within the $listen
array:
protected $listen = [
...
'Illuminate\Auth\Events\Login' => [
'App\Listeners\SyncShoppingCart',
],
];
Now whenever the user logs in, the App\Listeners\SyncShoppingCart::handle
method will be called and will add the items from the session cart to the database. Of course after a user is logged you should store new items added in the database as well, the session alone should be used to store cart info just for guests. On logout you can remove the cart from the session and be done with it, knowing that the cart contents are stored in the database and can be retrieved the next time the user logs in.
You can read more about Authentication Events, Sessions and Events in the Laravel Docs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With