Blazor 5x - قسمت 32 - احراز هویت و اعتبارسنجی کاربران Blazor WASM - بخش 2 - ثبت نام، ورود به سیستم و خروج از آن
نویسنده: وحید نصیری
تاریخ: ۱۴۰۰/۰۱/۱۰ ۱۸:۲۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
@page "/registration"
@inject IClientAuthenticationService AuthenticationService
@inject NavigationManager NavigationManager
<EditForm Model="UserForRegistration" OnValidSubmit="RegisterUser" class="pt-4">
<DataAnnotationsValidator />
<div class="py-4">
<div class=" row form-group ">
<div class="col-6 offset-3 ">
<div class="card border">
<div class="card-body px-lg-5 pt-4">
<h3 class="col-12 text-success text-center py-2">
<strong>Sign Up</strong>
</h3>
@if (ShowRegistrationErrors)
{
<div>
@foreach (var error in Errors)
{
<p class="text-danger text-center">@error</p>
}
</div>
}
<hr style="background-color:aliceblue" />
<div class="py-2">
<InputText @bind-Value="UserForRegistration.Name" class="form-control" placeholder="Name..." />
<ValidationMessage For="(()=>UserForRegistration.Name)" />
</div>
<div class="py-2">
<InputText @bind-Value="UserForRegistration.Email" class="form-control" placeholder="Email..." />
<ValidationMessage For="(()=>UserForRegistration.Email)" />
</div>
<div class="py-2 input-group">
<div class="input-group-prepend">
<span class="input-group-text"> +1</span>
</div>
<InputText @bind-Value="UserForRegistration.PhoneNo" class="form-control" placeholder="Phone number..." />
<ValidationMessage For="(()=>UserForRegistration.PhoneNo)" />
</div>
<div class="form-row py-2">
<div class="col">
<InputText @bind-Value="UserForRegistration.Password" type="password" id="password" placeholder="Password..." class="form-control" />
<ValidationMessage For="(()=>UserForRegistration.Password)" />
</div>
<div class="col">
<InputText @bind-Value="UserForRegistration.ConfirmPassword" type="password" id="confirm" class="form-control" placeholder="Confirm Password..." />
<ValidationMessage For="(()=>UserForRegistration.ConfirmPassword)" />
</div>
</div>
<hr style="background-color:aliceblue" />
<div class="py-2">
@if (IsProcessing)
{
<button type="submit" class="btn btn-success btn-block disabled"><i class="fas fa-sign-in-alt"></i> Please Wait...</button>
}
else
{
<button type="submit" class="btn btn-success btn-block"><i class="fas fa-sign-in-alt"></i> Register</button>
}
</div>
</div>
</div>
</div>
</div>
</div>
</EditForm>
@code{
UserRequestDTO UserForRegistration = new UserRequestDTO();
bool IsProcessing;
bool ShowRegistrationErrors;
IEnumerable<string> Errors;
private async Task RegisterUser()
{
ShowRegistrationErrors = false;
IsProcessing = true;
var result = await AuthenticationService.RegisterUserAsync(UserForRegistration);
if (result.IsRegistrationSuccessful)
{
IsProcessing = false;
NavigationManager.NavigateTo("/login");
}
else
{
IsProcessing = false;
Errors = result.Errors;
ShowRegistrationErrors = true;
}
}
}
@page "/login"
@inject IClientAuthenticationService AuthenticationService
@inject NavigationManager NavigationManager
<div id="logreg-forms">
<h1 class="h3 mb-3 pt-3 font-weight-normal text-primary" style="text-align:center;">Sign In</h1>
<EditForm Model="UserForAuthentication" OnValidSubmit="LoginUser">
<DataAnnotationsValidator />
@if (ShowAuthenticationErrors)
{
<p class="text-center text-danger">@Errors</p>
}
<InputText @bind-Value="UserForAuthentication.UserName" id="email" placeholder="Email..." class="form-control mb-2" />
<ValidationMessage For="(()=>UserForAuthentication.UserName)"></ValidationMessage>
<InputText @bind-Value="UserForAuthentication.Password" type="password" placeholder="Password..." id="password" class="form-control mb-2" />
<ValidationMessage For="(()=>UserForAuthentication.Password)"></ValidationMessage>
@if (IsProcessing)
{
<button type="submit" class="btn btn-success btn-block disabled"><i class="fas fa-sign-in-alt"></i> Please Wait...</button>
}
else
{
<button type="submit" class="btn btn-success btn-block"><i class="fas fa-sign-in-alt"></i> Sign in</button>
}
<a href="/registration" class="btn btn-primary text-white mt-3"><i class="fas fa-user-plus"></i> Register as a new user</a>
</EditForm>
</div>
@code
{
AuthenticationDTO UserForAuthentication = new AuthenticationDTO();
bool IsProcessing = false;
bool ShowAuthenticationErrors;
string Errors;
string ReturnUrl;
private async Task LoginUser()
{
ShowAuthenticationErrors = false;
IsProcessing = true;
var result = await AuthenticationService.LoginAsync(UserForAuthentication);
if (result.IsAuthSuccessful)
{
IsProcessing = false;
var absoluteUri = new Uri(NavigationManager.Uri);
var queryParam = HttpUtility.ParseQueryString(absoluteUri.Query);
ReturnUrl = queryParam["returnUrl"];
if (string.IsNullOrEmpty(ReturnUrl))
{
NavigationManager.NavigateTo("/");
}
else
{
NavigationManager.NavigateTo("/" + ReturnUrl);
}
}
else
{
IsProcessing = false;
Errors = result.ErrorMessage;
ShowAuthenticationErrors = true;
}
}
}
<AuthorizeView>
<Authorized>
<li class="nav-item p-0">
<NavLink class="nav-link" href="#">
<span class="p-2">
Hello, @context.User.Identity.Name!
</span>
</NavLink>
</li>
<li class="nav-item p-0">
<NavLink class="nav-link" href="logout">
<span class="p-2">
Logout
</span>
</NavLink>
</li>
</Authorized>
<NotAuthorized>
<li class="nav-item p-0">
<NavLink class="nav-link" href="registration">
<span class="p-2">
Register
</span>
</NavLink>
</li>
<li class="nav-item p-0">
<NavLink class="nav-link" href="login">
<span class="p-2">
Login
</span>
</NavLink>
</li>
</NotAuthorized>
</AuthorizeView> @page "/logout"
@inject IClientAuthenticationService AuthenticationService
@inject NavigationManager NavigationManager
@code
{
protected async override Task OnInitializedAsync()
{
await AuthenticationService.LogoutAsync();
NavigationManager.NavigateTo("/");
}
} namespace BlazorWasm.Client.Services
{
public class AuthStateProvider : AuthenticationStateProvider
{
// ...
public void NotifyUserLoggedIn(string token)
{
var authenticatedUser = new ClaimsPrincipal(
new ClaimsIdentity(JwtParser.ParseClaimsFromJwt(token), "jwtAuthType")
);
var authState = Task.FromResult(new AuthenticationState(authenticatedUser));
base.NotifyAuthenticationStateChanged(authState);
}
public void NotifyUserLogout()
{
var authState = Task.FromResult(new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())));
base.NotifyAuthenticationStateChanged(authState);
}
}
} namespace BlazorWasm.Client.Services
{
public class ClientAuthenticationService : IClientAuthenticationService
{
private readonly HttpClient _client;
private readonly ILocalStorageService _localStorage;
private readonly AuthenticationStateProvider _authStateProvider;
public ClientAuthenticationService(
HttpClient client,
ILocalStorageService localStorage,
AuthenticationStateProvider authStateProvider)
{
_client = client;
_localStorage = localStorage;
_authStateProvider = authStateProvider;
}
public async Task<AuthenticationResponseDTO> LoginAsync(AuthenticationDTO userFromAuthentication)
{
// ...
if (response.IsSuccessStatusCode)
{
//...
((AuthStateProvider)_authStateProvider).NotifyUserLoggedIn(result.Token);
return new AuthenticationResponseDTO { IsAuthSuccessful = true };
}
//...
}
public async Task LogoutAsync()
{
//...
((AuthStateProvider)_authStateProvider).NotifyUserLogout();
}
}
} @attribute [Authorize(Roles = ConstantRoles.Customer)]
@using Microsoft.AspNetCore.Authorization
@page "/hotel-room-details/{Id:int}"
// ...
@code {
// ...
protected override async Task OnInitializedAsync()
{
try
{
HotelBooking.OrderDetails = new RoomOrderDetailsDTO();
if (Id != null)
{
// ...
if (await LocalStorage.GetItemAsync<UserDTO>(ConstantKeys.LocalUserDetails) != null)
{
var userInfo = await LocalStorage.GetItemAsync<UserDTO>(ConstantKeys.LocalUserDetails);
HotelBooking.OrderDetails.UserId = userInfo.Id;
HotelBooking.OrderDetails.Name = userInfo.Name;
HotelBooking.OrderDetails.Email = userInfo.Email;
HotelBooking.OrderDetails.Phone = userInfo.PhoneNo;
}
}
}
catch (Exception e)
{
await JsRuntime.ToastrError(e.Message);
}
} public async Task<RoomOrderDetailsDTO> SaveRoomOrderDetailsAsync(RoomOrderDetailsDTO details)
{
// details.UserId = "unknown user!"; <AuthorizeView Roles="admin, superuser">
<p>You can only see this if you're an admin or superuser.</p>
</AuthorizeView> @if(context.User.IsInRole("Admin"))
{
}