در قسمت قبل، با نامهایی مانند IdentityRevalidatingAuthenticationStateProvider و PersistingRevalidatingAuthenticationStateProvider آشنا شدیم. در این قسمت جزئیات بیشتری از این کلاسها را بررسی میکنیم.
نحوهی پیاده سازی AuthenticationStateProvider در پروژههای Blazor Server 8x
در کدهای زیر، ساختار کلی کلاس AuthenticationStateProvider ارائه شدهی توسط قالب رسمی پروژههای Blazor Server به همراه مباحث اعتبارسنجی مبتنی بر ASP.NET Core Identity را مشاهده میکنید:
کار این کلاس، پیاده سازی کلاس پایهی RevalidatingServerAuthenticationStateProvider است. این کلاس پایه، چیزی نیست بجز یک کلاس پیاده سازی کنندهی AuthenticationStateProvider که در آن توسط حلقهای، کار یک تایمر را پیاده سازی کردهاند که برای مثال در اینجا هر نیم ساعت یکبار، متد ValidateAuthenticationStateAsync را صدا میزند.
برای مثال در اینجا (یعنی کلاس بازنویسی کنندهی متد ValidateAuthenticationStateAsync که توسط تایمر کلاس پایه فراخوانی میشود) اعتبار security stamp کاربر جاری، هر نیم ساعت یکبار بررسی میشود. اگر فاقد اعتبار بود، کلاس پایهی استفاده شده، سبب LogOut خودکار این کاربر میشود.
نحوهی پیاده سازی AuthenticationStateProvider در پروژههای Blazor WASM 8x
دو نوع پروژهی مبتنی بر وباسمبلی را میتوان در دات نت 8 ایجاد کرد: پروژههای حالت رندر Auto و پروژههای حالت رندر WASM
در هر دوی اینها، از کامپوننت ویژهای به نام PersistentComponentState استفاده شدهاست که معرفی آنرا در قسمت هشتم این سری مشاهده کردید. کار این کامپوننت در سمت سرور به صورت زیر است:
همانطور که مشاهده میکنید، مهمترین تفاوت آن با پروژههای Blazor Server، ذخیره سازی state به صورت JSON است که اینکار توسط کامپوننت PersistentComponentState انجام میشود و این Component-Stateهای مخفی حاصل از فراخوانی PersistAsJson، فقط یکبار توسط قسمت کلاینت، به صورت زیر خوانده میشوند:
در این کلاس سمت کلاینت و قرار گرفتهی در پروژههای WASM، نحوهی پیاده سازی AuthenticationStateProvider را مشاهده میکنید که توسط آن و به کمک PersistentComponentState، کار خواندن اطلاعات UserInfo ای که پیشتر توسط state.PersistAsJson_ در سمت سرور در انتهای HTML صفحه ذخیره شده بود، انجام میشود.
بنابراین PersistentComponentState کار پرکردن اطلاعات یک کش مانند را در سمت سرور انجام داده و آنرا به صورت سریالایز شده با قالب JSON، به انتهای HTML صفحه اضافه میکند. سپس زمانیکه کلاینت بارگذاری میشود، این اطلاعات را خوانده و استفاده میکند. یکبار از متد PersistAsJson آن در سمت سرور استفاده میشود، برای ذخیره سازی اطلاعات و یکبار از متد TryTakeFromJson آن در سمت کلاینت، برای خواندن اطلاعات.
یک نکته: پیاده سازی anti-forgery-token هم با استفاده از PersistentComponentState صورت گرفتهاست.
نحوهی پیاده سازی AuthenticationStateProvider در پروژههای Blazor Server 8x
در کدهای زیر، ساختار کلی کلاس AuthenticationStateProvider ارائه شدهی توسط قالب رسمی پروژههای Blazor Server به همراه مباحث اعتبارسنجی مبتنی بر ASP.NET Core Identity را مشاهده میکنید:
public class IdentityRevalidatingAuthenticationStateProvider : RevalidatingServerAuthenticationStateProvider { protected override TimeSpan RevalidationInterval => TimeSpan.FromMinutes(30); protected override async Task<bool> ValidateAuthenticationStateAsync( AuthenticationState authenticationState, CancellationToken cancellationToken) { // ... } }
برای مثال در اینجا (یعنی کلاس بازنویسی کنندهی متد ValidateAuthenticationStateAsync که توسط تایمر کلاس پایه فراخوانی میشود) اعتبار security stamp کاربر جاری، هر نیم ساعت یکبار بررسی میشود. اگر فاقد اعتبار بود، کلاس پایهی استفاده شده، سبب LogOut خودکار این کاربر میشود.
نحوهی پیاده سازی AuthenticationStateProvider در پروژههای Blazor WASM 8x
دو نوع پروژهی مبتنی بر وباسمبلی را میتوان در دات نت 8 ایجاد کرد: پروژههای حالت رندر Auto و پروژههای حالت رندر WASM
در هر دوی اینها، از کامپوننت ویژهای به نام PersistentComponentState استفاده شدهاست که معرفی آنرا در قسمت هشتم این سری مشاهده کردید. کار این کامپوننت در سمت سرور به صورت زیر است:
public class PersistingRevalidatingAuthenticationStateProvider : RevalidatingServerAuthenticationStateProvider { public PersistingRevalidatingAuthenticationStateProvider( ILoggerFactory loggerFactory, IServiceScopeFactory scopeFactory, PersistentComponentState state, IOptions<IdentityOptions> options) : base(loggerFactory) { // ... } protected override TimeSpan RevalidationInterval => TimeSpan.FromMinutes(30); protected override async Task<bool> ValidateAuthenticationStateAsync( AuthenticationState authenticationState, CancellationToken cancellationToken) { // ... } private async Task OnPersistingAsync() { // ... _state.PersistAsJson(nameof(UserInfo), new UserInfo { UserId = userId, Email = email, }); // ... } }
public class PersistentAuthenticationStateProvider(PersistentComponentState persistentState) : AuthenticationStateProvider { private static readonly Task<AuthenticationState> _unauthenticatedTask = Task.FromResult(new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()))); public override Task<AuthenticationState> GetAuthenticationStateAsync() { if (!persistentState.TryTakeFromJson<UserInfo>(nameof(UserInfo), out var userInfo) || userInfo is null) { return _unauthenticatedTask; } Claim[] claims = [ new Claim(ClaimTypes.NameIdentifier, userInfo.UserId), new Claim(ClaimTypes.Name, userInfo.Email), new Claim(ClaimTypes.Email, userInfo.Email) ]; return Task.FromResult( new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(claims, authenticationType: nameof(PersistentAuthenticationStateProvider))))); } }
بنابراین PersistentComponentState کار پرکردن اطلاعات یک کش مانند را در سمت سرور انجام داده و آنرا به صورت سریالایز شده با قالب JSON، به انتهای HTML صفحه اضافه میکند. سپس زمانیکه کلاینت بارگذاری میشود، این اطلاعات را خوانده و استفاده میکند. یکبار از متد PersistAsJson آن در سمت سرور استفاده میشود، برای ذخیره سازی اطلاعات و یکبار از متد TryTakeFromJson آن در سمت کلاینت، برای خواندن اطلاعات.
یک نکته: پیاده سازی anti-forgery-token هم با استفاده از PersistentComponentState صورت گرفتهاست.