雖然在上一篇文章(學習ASP.NET Core Blazor編程系列二十三——登錄(2) )中我們製作出了登錄頁面,但那個登錄頁面,不符合我們平時使用的樣式,需要進行修改,同時也沒有實現登錄驗證。這一文章學習如何對Login.razor使用特有的佈局組件,實現正常的登錄樣式,學習使用AuthenticationStateProvider類來進行登錄驗證。
五、LoginLayout組件
登錄頁面的佈局與之前的內容頁面中的佈局是不一樣的。例如之前的圖書編輯頁面是有側邊導航欄的,但登錄頁面顯然是不需要的。因此,我們需要單獨寫一個LoginLayout組件,和默認佈局MainLayout分開,只用於Login頁面:
1. 在Visual Studio 2022的解決方案資源管理器中,鼠標左鍵選中“Pages”文件夾,右鍵單擊,在彈出菜單中選擇“添加—>Razor組件…”,並將組件命名爲“LoginLayout.razor”。
2.在Visual Studio 2022的文本編輯器中打開LoginLayout.razor,我們來創建登錄頁面的佈局。代碼中的“/imgs/logo.png”所指定的logo圖片,請自行準備。具體代碼如下:
@inherits LayoutComponentBase
<div class="container">
<div class="card">
<div class="card-header" style="height:10%">
<div style="margin:10px;">
<div class="row">
<div class="col-8">
<img src="/imgs/logo.png" style="align-self:center" />
</div>
<div class="col-8 text-center">
<span style="color:black; font-size:24px">歡迎使用 @ProductionName 後臺管理系統</span>
</div>
</div>
</div>
</div>
<div class="card-body" Style="background-color:white; min-height:500px">
<div class="row">
<div class="col-3"></div>
<div class="col-6">
<div style="margin:100px 0">
@Body
</div>
</div>
</div>
</div>
<div class="card-footer">
<small class="text-muted">Copyright @Year 圖書租賃系統 Powered by .NET 6.0 </small>
</div>
</div>
</div>
@code {
private const string ProductionName = "圖書租賃";
private int Year = DateTime.Now.Year;
}
六. 修改Login.razor
1.在Visual Studio 2022的文本編輯器中打開Login.razor,我們修改一下登錄頁面。具體代碼如下:
@page "/Login"
@using BlazorAppDemo.Models
@using BlazorAppDemo.Utils
@layout LoginLayout
@inject NavigationManager NavigationManager
<div class="card align-items-center">
<div class="card-body my-2">
<h3>Login</h3>
<hr />
<EditForm Model="loginModel" OnValidSubmit="SubmitHandler" OnInvalidSubmit="InvalidHandler">
<DataAnnotationsValidator />
<div class="form-group">
<label for="userName"> @HtmlHelper.GetDisplayName(loginModel ,m=> m.UserName)</label>
<InputText @bind-Value="loginModel.UserName" class="form-control" id="userName" />
<ValidationMessage For="()=>loginModel.UserName" />
</div>
<div class="form-group">
<label for="pwd"> @HtmlHelper.GetDisplayName(loginModel ,m=> m.Password)</label>
<InputPassword @bind-Value="loginModel.Password" class="form-control" id="pwd" />
<ValidationMessage For="()=>loginModel.Password" />
</div>
<span class="form-control-plaintext"></span>
<div class="form-group row">
<div class="col-sm-10">
<button class="btn btn-primary">登錄</button>
</div>
</div>
</EditForm>
</div>
</div>
@code {
private UserInfo loginModel = new UserInfo();
private void SubmitHandler()
{
Console.WriteLine($"用戶名:{loginModel.UserName} ,密碼:{loginModel.Password}");
NavigationManager.NavigateTo("/Index");
}
private void InvalidHandler()
{
Console.WriteLine($"用戶名: {loginModel.UserName} ,密碼:{loginModel.Password}");
}
}
七、修改路由與啓動頁面
如何讓Blazor知道當用登錄用戶是被授權訪問的?答案是Blazor提供的AuthenticationStateProvider。如果razor組件使用CascadingAuthenticationState,Blazor在渲染前會檢查AuthorizeRouteView中的/AuthorizeView/Authorized, NotAuthorized, Authorizing標籤,並根據獲取的信息在客戶端進行渲染成是授權的UI,還是未授權的UI。
1.在Visual Studio 2022的文本編輯器中打開app.razor,我們來添加CascadingAuthenticationState組件。具體代碼如下:
@using Microsoft.AspNetCore.Components.Authorization
<CascadingAuthenticationState>
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<h1>頁面走失!請確認輸入的URL是否正確!</h1>
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
2. 在Visual Studio 2022的文本編輯器中打開MainLayou.razor,我們來添加AuthorizeView組件。具體代碼如下:
@inherits LayoutComponentBase
<PageTitle>BlazorAppDemo</PageTitle>
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<AuthorizeView>
<Authorized>
<div class="top-row px-4">
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
</Authorized>
<NotAuthorized>
<div style="margin: 120px 0; width:100%; text-align: center; color: red;">
<span style="font-size:20px">檢測到登錄超時,請重新<a href="/login" style="text-decoration:underline">登錄</a>!</span>
</div>
</NotAuthorized>
</AuthorizeView>
</main>
</div>
4.使用鼠標左鍵點擊“登錄”超連接,頁面進入到登錄頁面。如下圖。