今天來實現身分驗證的部分,筆者此前是用ASP.NET Core Web API 搭配Blazor,用戶第一次成功登入時,在後端將Role、Claim 等權限儲存在JWT,將JWT 存在瀏覽器的LocalStorage 裡面,前端再自己重寫AuthenticationStateProvider,去檢查LocalStorage 的JWT,接著將AuthenticationState 當作CascadingParameter 層層傳遞到各Component,這樣就不需要不停跟後端交換資料,這是個很寶貴的經驗,讓筆者對身分驗證有深入了解,這次筆者試試看ASP.NET Core 自己的Identity。
首先去 NuGet 下載 3 個元件,分別為Microsoft.AspNetCore.Identity.EntityFrameworkCore、Microsoft.AspNetCore.Identity.UI、Microsoft.VisualStudio.Web.CodeGeneration.Design,第 1 個是Identity 必備元件,如果想自己實現JWT 的話,只需要下載第一個元件,再下載JWT 相關元件(Microsoft.AspNetCore.Authentication.JwtBearer)即可,後面 2 個都是讓ASP.NET Core Identity幫我們生成預置Identity 頁面的元件。
接著去BlazorServer.Models的AppDbContext,將繼承的DbContext改為IdentityDbContext,代表接下來用的DB 跟Identity有關連。

在BlazorServer 專案按右鍵,選擇「新增」,選擇「新搭建 Scaffold 的專案」,切換到「身分識別」頁籤,選擇身分識別。


勾選「取代所有檔案」,資料內容類別選擇AppDbContext,要注意的是,如果剛才沒將繼承的類別改成IdentityDbContext,就不會有AppDbContext可以選,必須點右邊的「+」符號自己新增一個IdentityDbContext。

這時候有可能遇到這種「FileUpload.OnInitializedAsync(): 沒有找到適合的方法來覆寫」的錯誤訊息,這通常是Visual Studio 的問題,先將這裡註解,重複一次上一段的做法就可以。


接著去Program.cs加上身分驗證的服務,Identity 預設將驗證資訊存在 Cookie。

接著在「套件管理員主控台」執行兩段命令,Add-Migration IdentitySupport新增Migration,Update-Database更新DB,去看資料庫,可以看到「多了 6 張表」,其中最常用到的就是AspNetUsers、AspNetRoles 及AspNetUserRoles,如果以Claim 處理權限的話,就會用到AspNetUserClaims。

專案則多了一個Areas 資料夾,裡面就是ASP.NET Core Identity 的實現,包括了「登入系統」、「帳號系統」、「管理系統」。

我們去NavMenu.razor加上通往Login 的NavLink,在相對路徑中Areas 跟Pages 可以省略。
<div class="nav-item px-3">
<NavLink class="nav-link" href="Identity/Account/Login" Match="NavLinkMatch.All">
<span class="bi bi-file-earmark-lock2 h4 p-2 mb-0" aria-hidden="true"></span> Login
</NavLink>
</div>
啟動網站後,從左邊 Nav 前往 Login 頁面,可以看到已經有個完善的登入系統,包括註冊、登入、忘記密碼等等功能,就連註冊密碼的規則也有,我們照規則註冊一個帳號,資料庫也生成了剛剛註冊的帳號。

註冊介面填寫正確的 Email 和密碼,AspNetUsers表即可查看註冊的使用者資訊:

引用
- Claims-based authorization in ASP.NET Core
- Claim type and claim value in claims policy based authorization in asp net core
- ASP NET Core Identity tutorial from scratch
- Unable to resolve service for type IEmailSender while attempting to activate RegisterModel
註:本文程式碼透過 .NET 6 + Visual Studio 2022 重構,可點擊原文連結與重構後程式碼比較學習,謝謝閱讀,支持原作者