迁移匿名会话数据并将其限制为经过身份验证的用户


Migrating anonymous session data and restricting it to authenticated user

现在,我的 Web 应用程序的匿名(未经身份验证)用户的会话数据不会在用户登录或注册后移动/分配给用户。

例如:匿名用户与应用程序交互,创建一些会话数据(例如购物车中的产品),然后登录/注册,然后注销,会话数据仍然可以访问,并且不会移动/使其无法访问现在未经身份验证的用户。

正在使用文件会话驱动程序(没有数据库),也许有人可以提供一些需要更改的示例(我假设在会话配置中),以使匿名用户创建的任何会话数据分配给该用户,并且只有在他们通过登录或注册进行身份验证后才能访问该用户,并且仅在用户进行身份验证时进行身份验证。

这样做的要求是因为应用程序的用户创建唯一的对象(绑定到他们的user_id),这些对象仅在订单处理运行时付款后保留。我将它们存储在会话中,直到用户登录/注册并完成最终的订单步骤,然后它们才会持久化。因此,在用户注销后,我绝对不能将用户特定的对象保留在未经身份验证的会话中。我可以在注销时刷新会话,但理想情况下,我想在用户重新登录时保留它们。

身份验证系统仅将会话用作存储,以跨请求保留身份验证状态。但是,Laravel的身份验证系统不负责处理您的所有会话数据,它只关心存储与身份验证相关的信息,例如用户详细信息。如果要为经过身份验证的用户处理其他会话数据,则需要手动执行此操作。

逻辑很简单:

  • 如果用户执行某些操作(例如向购物车添加某些内容),则当会话通过 cookie 绑定到请求来自的浏览器时,数据将保留在那里。

  • 如果用户从同一浏览器登录,Laravel的身份验证系统会检查凭据,如果凭据正确,它会在同一会话中存储有关该用户的必要信息。以前存储的有关购物车的数据仍然存在且保持不变,因此您可以在登录用户的上下文中使用它。如果此时您想要保留会话购物车,以便用户将来访问他/她的帐户时可以使用它,那么您需要将详细信息存储在数据库中。以下是展示实现这一目标的方法的几个步骤:

1. 创建一个事件侦听器,我们将其命名为 SyncShoppingCart ,它将侦听 Illuminate'Auth'Events'Login 事件(命令中的双反斜杠需要''来转义单个斜杠):

php artisan make:listener SyncShoppingCart --event=Illuminate''Auth''Events''Login

2. 上一个命令在app/Listeners中创建了一个名为 SyncShoppingCart.php 的文件。现在,您只需要在该类的handle方法中将购物车数据存储在用户的购物车中。下面的示例假定您cart_item表存储有关添加到购物车的物料的信息,并且您为其定义了CartItem模型。此示例已简化,您需要对其进行修改以满足您的需求,但它是理解此方法的良好起点:

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. 然后在 $listen 数组的app/Providers/EventServiceProvider.php中注册偶数侦听器:

protected $listen = [
    ...
    'Illuminate'Auth'Events'Login' => [
        'App'Listeners'SyncShoppingCart',
    ],
];

现在,每当用户登录时,都会调用 App'Listeners'SyncShoppingCart::handle 方法,并将会话购物车中的项目添加到数据库中。当然,在用户登录后,您也应该存储添加到数据库中的新项目,会话本身应该用于存储仅供客人使用的购物车信息。注销时,您可以从会话中删除购物车并完成它,因为知道购物车内容存储在数据库中,并且可以在用户下次登录时检索。


您可以在Laravel文档中阅读有关身份验证事件,会话和事件的更多信息。