Browse Source

Merge pull request #74 from abpframework/gterdem/anonymous_user_refactor

eShopOnAbp: Refactor anonymous user
ipaddr
Galip Tolga Erdem 5 years ago
committed by GitHub
parent
commit
9f6d7cb583
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      apps/auth-server/src/EShopOnAbp.AuthServer/AnonymousUserItem.cs
  2. 82
      apps/auth-server/src/EShopOnAbp.AuthServer/EShopUserClaimsPrincipalFactory.cs
  3. 46
      apps/public-web/src/EShopOnAbp.PublicWeb/AnonymousUser/AnonymousUserMiddleware.cs
  4. 48
      apps/public-web/src/EShopOnAbp.PublicWeb/Components/AnonymousUser/AnonymousUserViewComponent.cs
  5. 3
      apps/public-web/src/EShopOnAbp.PublicWeb/Components/AnonymousUser/Default.cshtml
  6. 2
      apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs
  7. 6
      apps/public-web/src/EShopOnAbp.PublicWeb/Pages/_ViewStart.cshtml
  8. 1
      shared/EShopOnAbp.Shared.Hosting.AspNetCore/EShopConstants.cs

6
apps/auth-server/src/EShopOnAbp.AuthServer/AnonymousUserItem.cs

@ -1,6 +0,0 @@
namespace EShopOnAbp.AuthServer;
public class AnonymousUserItem
{
public string AnonymousUserId { get; set; }
}

82
apps/auth-server/src/EShopOnAbp.AuthServer/EShopUserClaimsPrincipalFactory.cs

@ -1,82 +0,0 @@
using System;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using EShopOnAbp.Shared.Hosting.AspNetCore;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
using Volo.Abp.Security.Claims;
using IdentityRole = Volo.Abp.Identity.IdentityRole;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
namespace EShopOnAbp.AuthServer;
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(AbpUserClaimsPrincipalFactory))]
public class EShopUserClaimsPrincipalFactory : AbpUserClaimsPrincipalFactory
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly ILogger<EShopUserClaimsPrincipalFactory> _logger;
private readonly IDistributedCache<AnonymousUserItem, Guid> _cache;
protected HttpContext HttpContext => _httpContextAccessor.HttpContext;
public EShopUserClaimsPrincipalFactory(
UserManager<IdentityUser> userManager,
RoleManager<IdentityRole> roleManager,
IOptions<IdentityOptions> options,
ICurrentPrincipalAccessor currentPrincipalAccessor,
IAbpClaimsPrincipalFactory abpClaimsPrincipalFactory,
IHttpContextAccessor httpContextAccessor,
ILogger<EShopUserClaimsPrincipalFactory> logger,
IDistributedCache<AnonymousUserItem, Guid> cache) : base(userManager,
roleManager,
options,
currentPrincipalAccessor,
abpClaimsPrincipalFactory)
{
_httpContextAccessor = httpContextAccessor;
_logger = logger;
_cache = cache;
}
public override async Task<ClaimsPrincipal> CreateAsync(IdentityUser user)
{
var principal = await base.CreateAsync(user);
if (HttpContext.Request.Cookies.ContainsKey(EShopConstants.AnonymousUserClaimName))
{
HttpContext.Request.Cookies.TryGetValue(EShopConstants.AnonymousUserClaimName, out var anonymousUserId);
await _cache.SetAsync(user.Id, new AnonymousUserItem {AnonymousUserId = anonymousUserId},
options: new DistributedCacheEntryOptions()
{
AbsoluteExpiration = DateTimeOffset.UtcNow.AddSeconds(60)
});
_logger.LogInformation($"Cached anonymousUserId:{anonymousUserId}.");
}
var cachedItem = await _cache.GetAsync(user.Id);
if (cachedItem == null)
{
_logger.LogWarning($"Could not retrieve anonymousUserId from cache.");
return principal;
}
_logger.LogInformation($"Retrieved anonymousUserId:{cachedItem.AnonymousUserId} from cache.");
principal.Identities.First().AddClaim(
new Claim(
EShopConstants.AnonymousUserClaimName,
cachedItem.AnonymousUserId
)
);
return principal;
}
}

46
apps/public-web/src/EShopOnAbp.PublicWeb/AnonymousUser/AnonymousUserMiddleware.cs

@ -0,0 +1,46 @@
using System;
using System.Threading.Tasks;
using EShopOnAbp.Shared.Hosting.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
namespace EShopOnAbp.PublicWeb.AnonymousUser;
public class AnonymousUserMiddleware
{
private readonly RequestDelegate _next;
public AnonymousUserMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
if (context.Request.Method == "GET")
{
context.Request.Cookies.TryGetValue(EShopConstants.AnonymousUserClaimName, out string anonymousUserId);
// Generate guid for anonymous user id and set to cookie for 14 days
if (string.IsNullOrEmpty(anonymousUserId))
{
anonymousUserId = Guid.NewGuid().ToString();
context.Response.Cookies.Append(EShopConstants.AnonymousUserClaimName, anonymousUserId,
new CookieOptions
{
SameSite = SameSiteMode.Lax,
Expires = DateTimeOffset.UtcNow.AddDays(14)
});
}
}
await _next(context);
}
}
public static class AnonymousUserApplicationBuilderExtensions
{
public static IApplicationBuilder UseAnonymousUser(this IApplicationBuilder app)
{
app.UseMiddleware<AnonymousUserMiddleware>();
return app;
}
}

48
apps/public-web/src/EShopOnAbp.PublicWeb/Components/AnonymousUser/AnonymousUserViewComponent.cs

@ -1,48 +0,0 @@
using System.Threading.Tasks;
using EShopOnAbp.Shared.Hosting.AspNetCore;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI.Widgets;
using Volo.Abp.Guids;
namespace EShopOnAbp.PublicWeb.Components.AnonymousUser;
/* TODO: Convert this to an ASP.NET Core middleware */
[Widget(
AutoInitialize = true
)]
public class AnonymousUserViewComponent : AbpViewComponent
{
private readonly ILogger<AnonymousUserViewComponent> _logger;
private readonly IGuidGenerator _guidGenerator;
public AnonymousUserViewComponent(ILogger<AnonymousUserViewComponent> logger, IGuidGenerator guidGenerator)
{
_logger = logger;
_guidGenerator = guidGenerator;
}
public async Task<IViewComponentResult> InvokeAsync()
{
// Get anonymous user id from cookie
HttpContext.Request.Cookies.TryGetValue(EShopConstants.AnonymousUserClaimName,
out string anonymousUserId);
_logger.LogInformation($"========= Anonymous User Id from Cookie:{anonymousUserId} ========= ");
// Generate new id for anonymous user
if (string.IsNullOrEmpty(anonymousUserId))
{
anonymousUserId = _guidGenerator.Create().ToString();
HttpContext.Response.Cookies.Append(EShopConstants.AnonymousUserClaimName, anonymousUserId,
new CookieOptions
{
SameSite = SameSiteMode.Lax
});
_logger.LogInformation(
$"========= Generated new User Id:{anonymousUserId} ========= APPENDED TO COOKIE ====== ");
}
return await Task.FromResult(View("~/Components/AnonymousUser/Default.cshtml"));
}
}

3
apps/public-web/src/EShopOnAbp.PublicWeb/Components/AnonymousUser/Default.cshtml

@ -1,3 +0,0 @@
<div>
</div>

2
apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs

@ -38,6 +38,7 @@ using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Bundling;
using EShopOnAbp.PublicWeb.Components.Toolbar.Cart;
using EShopOnAbp.PublicWeb.PaymentMethods;
using EShopOnAbp.PaymentService.PaymentMethods;
using EShopOnAbp.PublicWeb.AnonymousUser;
using Microsoft.Extensions.Configuration;
namespace EShopOnAbp.PublicWeb;
@ -202,6 +203,7 @@ public class EShopOnAbpPublicWebModule : AbpModule
app.UseAuthentication();
app.UseAbpSerilogEnrichers();
app.UseAuthorization();
app.UseAnonymousUser();
app.UseConfiguredEndpoints(endpoints =>
{
endpoints.MapReverseProxy();

6
apps/public-web/src/EShopOnAbp.PublicWeb/Pages/_ViewStart.cshtml

@ -1,7 +1,5 @@
@using EShopOnAbp.PublicWeb.Components.AnonymousUser
@using Volo.Abp.AspNetCore.Mvc.UI.Theming
@using Volo.Abp.AspNetCore.Mvc.UI.Theming
@inject IThemeManager ThemeManager
@{
Layout = ThemeManager.CurrentTheme.GetPublicLayout();
}
@await Component.InvokeAsync(typeof(AnonymousUserViewComponent))
}

1
shared/EShopOnAbp.Shared.Hosting.AspNetCore/EShopConstants.cs

@ -2,6 +2,5 @@
public static class EShopConstants
{
// public const string AnonymousUserCookieName = "eshop_anonymousId";
public const string AnonymousUserClaimName = "anonymous_id";
}
Loading…
Cancel
Save