问题
I am building an online store website as a side project with Laravel 5.3. My goal is to implement anonymous and authenticated shopping. Here are the Customer
, Cart
, and CartItem
tables so far:
// (1) customers table...
table->increments('id');
$table->integer('user_id')->unsigned(); // -> User hasOne('App\Customer') rel.
$table->string('first_name');
// last_name, dob, phone, etc. + timestamps
// (2) carts table...
$table->increments('id');
// -> Customer identification (and not user_id, because admins don't have carts!):
$table->integer('customer_id')->unsigned()->nullable();
// -> Guest identification:
$table->string('session_id');
$table->timestamps();
// (3) cart_items table...
$table->increments('id');
$table->integer('cart_id')->unsigned();
$table->integer('product_id')->unsigned();
$table->integer('quantity')->unsigned();
$table->timestamps();
However, I am not sure how to identify guest users and bind them with carts. The idea is, if you shop as a guest and then register or log in, your cart should become authenticated, i.e. I need to do $cart->customer_id = Auth::user()->customer->id
. But how do I bind guests with their anonymous carts (i.e. when $cart->customer_id == null
)?
Approaches
- If I store
Session::getId();
in$cart->session_id
whenever a newCart
is created, then I am at risk, because session id in Laravel is regenerated quite frequently (e.g. during login authentication). So, if a guest logs in, I can no longer find their cartCart::where('session_id', Session::getId())
because theirSession
id has just been regenerated upon login! - Another option would be to store a random string instead of
session_id
, e.g. write$table->uuid('guest_id')
incarts
migration. This token would be persisted in the database and in the client-side cookie (as suggested by Snapey in a similar question on Laracasts). - Yet another option is to create a 'guest'
User
, possibly with a role ofguest
, but with no password or email. When customer decides to register, I could then populate those fields with the values from the registration form.
Considerations
The problem I see with cookies though is that they are less 'persistent', and I still feel that storing the cart (both anonymous and authenticated) in session is more secure. At the same time, I can't change session lifetime
to e.g. 30 days, since sessions also store authentication info and since this might simply be an overkill for the server. As for guest users, I would need to make email
and password
nullable in users
table, which smells like a bad practice (don't change code you don't own type of thing).
Question
Are there any other approaches to solving this problem? What would be the best and most secure practice to identify guest users and bind them with their anonymous shopping carts? Lastly, if I were to use Laravel sessions, does it make sense to use database
sessions or rather file
sessions? Do I need any changes to my customers
, carts
, or cart_items
tables?
P.S. I am aware that shopping cart packages for Laravel do exist, but so far I haven't found one that incorporates anonymous + authenticated shopping and/or integrates with users
table.
来源:https://stackoverflow.com/questions/41201788/identifying-and-persisting-guest-users-in-laravel