Challenges getting to this middleware explained
In Commerce 13 and below, IProfileMigrator was called from an authentication event called MigrateAnonymous attached in httpmodule. Aspnetcore 5 and above doesn't have httpmodules and there doesn't seem to be any appropriate migration event I can take advantage of at the time of writing this post. There are events associated with cookie authentication such as SigningIn, SignedIn and ValidatePrincple; but occur too early in the pipeline for the user object to be instantiated and the correct Customer Contact to be loaded. The same also goes for IAuthorizationMiddlewareResultHandler as implementing this interface allows you check the authorization result and can be useful to target a challenge response but not so useful for targeting a successful authentication.
As a result of this, we have to do additional checks against the state of the anonymous cart and the user principal object to make sure the migrate code is only run once, after the customer logs in.
- User.Identity isn't null
- Name in User.Identity isn't null or empty
- User is Authenticated
- Anonymous ID isn't null
- Anonymous cart isn't null
- Anonymous cart has at least one line item
These guards should be enough to ensure the MigrateCarts called is called and not called again on the next subsequent request.
The example above only shows MigrateCarts but you can also add in MigrateOrders and MigrateWishlists depending on your client requirements.
With the middleware example above. We are attempting to only run the code when the user is authenticated. So within the pipeline, the middleware should be called after the UseAuthentication is called.
app.UseAuthentication();
app.UseAuthorization();
app.EnableAnonymousCartMerging();