昨天做的驗證只針對 Identity 系統,沒有包含到我們的日誌,如果在未登入狀態下於網址列輸入https://localhost:44327/Blog
,還是可以看到部落格,讓我們整合驗證。
首先在Blog.razor
外層加上<AuthorizeView>
,這表示包在其中的內容呈現與否的條件為使用者是否獲得驗證,接著在Blog
內容外加上<Authorized>
,顧名思義就是通過驗證才能看到內容,另外新增一段未通過驗證的<NotAuthorized>
程式碼。這邊要記得加上Context="IdentityContext"
,否則會跟Blog
的<EditForm>
本身的context
產生衝突。
再去App.razor
用<CascadingAuthenticationState>
將原本的<Router>
包裹,告訴 Blazor 所有 Component 都必須經過驗證。
然後是NavMenu.razor
,<Authorized>
Component 加上登出連結,登入連結則移到<NotAuthorized>
,icon 也改一下。
這時候要重新啟動系統,驗證機制才會生效,可以看到確實擋住了未驗證訪問。
在登入前,先打開 Dev Tool 的 Application 頁籤去看Cookies,目前只有一個 Cookie。
登入後看到新的 Cookie,這就是我們的 Authentication Cookie。
接著來試試看登出,點擊左邊的 Logout,並沒有如想像中登出,而是來到一個 Log out 頁面,右上角還是登入狀態,Authentication Cookie 也還在。
我們去看Logout.cshtml.cs
,裡面有OnGet()
跟OnPost()
分別對應HttpGet
及HttpPost
,我們從連結點過來的作法是HttpGet
,但OnGet()
這裡什麼事都沒做,OnPost()
則呼叫 ASP.NET Core Identity API 將使用者登出。
Logout.cshtml
也找到了一個<form>
元素,asp-page
這些asp-
開頭的程式是 ASP.NET Core 的Tag Helper (標籤協助程式),類似 Angular 的 *ngFor,這邊先略過不提,我們看到這裡用了method="post"
,還有個<button type="submit">
,對應了剛才的OnPost()
。
通常不會有使用者按了登出後還要再按一次登出,所以我們這邊改動一下,先給<form>
加上id="logoutFormInLogout"
,再加上一段<script>
,這裡用到 IIFE(Immediately Invoked Functions Expressions),意即不需要呼叫就會執行的函式,一旦使用者進入這頁面就會將<form>
送出,如此一來,只要點擊NavMenu
左邊的 Logout 連結,就可以順利登出了。
如果不想要加上id="logoutFormInLogout"
這麼長的 id,也可以用id="logoutForm"
就好,根目錄下的 Pages/Shared/_LoginPartial.cshtml裡面有個登出的<form>
已經定義了id="logoutForm"
這個 id。
不過現在登出後還停留在 Log out頁面似乎沒有意義,所以將OnPost()
的else
區塊改成return LocalRedirect("~/Blog");
,這樣登出後就會回到未驗證的 Blog 頁面。
這樣一來就完成了單一專案的登入驗證機制,而且各種功能、頁面一應俱全,如果只是小型專案的話可以這麼做,明天就來說明這些 ASP.NET Core 的驗證原理。
Ref:立即函式 IIFE
Ref:Blazor cookie authentication Logout page