Vulnerability in EPiServer.Forms
Has anyone implemented a shared cart for B2C websites ?
Scenario is user can shop across multiple brand sites using a single cart. I'd be interested in understanding how it can be achieved without requiring the user to log in.
What challenges are you facing?
I guess this is obvious for, as a certified developer, but...
Looking at the documentation, you can see how a cart is created or loaded:
var cart = orderRepository.LoadOrCreateCart<ICart>(_customerContext.CurrentContactId, name)
You should simply exchange _customerContext.CurrentContactId and name for something else, but as you understand, you would need a way to pass those parameters between the different websites, for example via cookies or query parameters. And of course, this requires the websites to share the same database.
The main obvious challenge for anonymous users is how do you load the same cart when the _customerContext.CurrentContactId is unique between the sites. I don't quite follow your statement "You should simply exchange _customerContext.CurrentContactId and name for something else". As you are probably aware, cart is associated to a ContactId. Also for the purposes of shared cart you would want to set the cart type (i.e name) to be the same.
The basis of passing parameters between websites is that you have central trigger where users navigate to the different websites, however users can also directly navigate to the websites. Syncing cookies across multiple sites is in itself another challenge
The possible solution I see is override the CustomerContext implementation to ensure the _customerContext.CurrentContactId returns the same contactId for the different sites However yet to test the viability of this. Keen to hear if anyone has implemented B2C shared cart
`As you are probably aware, cart is associated to a ContactId.`- Not really. You fetch a cart by passing a GUID and a name. The guid variable is called customerId but it could be anything. Nothing forces you to use _customerContext.CurrentContactId. Rather than overriding _customerContext.CurrentContactId, maybe you should create some method called GetCartId(...someValues) which determines whether to use a shared cart or something else.
Really, this question has nothing to do with Episerver. From what I can understand, you simply want a way to share a state over multiple websites. Easy if all the websites are hosted as the same web application, more difficult if not.
The GUID parameter is supposed to be a CustomerId. If a visitor is not logged in, the CustomerId will be the HttpRequest.AnonymousID which is persisted in a cookie.True, the GUID parameter could be anything (no constraints), but that's just like asking for trouble in the future. There is another method, IOrderRepository.Load<TOrderGroup>(int orderGroupId), that expects the specific CartId.
The hard part of this shared cart would probably be sharing anonymous state (the AnonymousID) between sites, unless they are on a subdomain to the same main domain. But if you could share the cookie between sites, the AnonymousID could theoretically let you share a single cart.However, if the user logs in on one of the sites, then the anonymous cart will automatically be changed/merged into the logged-in users cart. But on the other sites the anonymous cookie would still be there, now pointing to a missing cart that will be re-added as an empty cart on first request.
Thanks for the insights Stefan .
A solution that doesn't require customising the built-in cart functionality would be the ideal result. Being able to share the AnonymousId cookie across multiple sites (on different domains) seems like the way to go. This would likely involve customising the cookie authentication provider