forked from tsai/eShopOnAbp
committed by
GitHub
8 changed files with 50 additions and 144 deletions
@ -1,6 +0,0 @@ |
|||
namespace EShopOnAbp.AuthServer; |
|||
|
|||
public class AnonymousUserItem |
|||
{ |
|||
public string AnonymousUserId { get; set; } |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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")); |
|||
} |
|||
} |
|||
@ -1,3 +0,0 @@ |
|||
<div> |
|||
|
|||
</div> |
|||
@ -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)) |
|||
} |
|||
Loading…
Reference in new issue