昨日行った検証は Identity システムのみを対象としており、ログには含まれていません。未ログイン状態でアドレスバーに https://localhost:5018/Blog を入力するとブログがまだ表示されるため、認証を統合しましょう。
まず、Blog.razor の外側に <AuthorizeView> を追加します。これにより、その中に含まれるコンテンツの表示条件がユーザーの認証状態になります。次に、Blog のコンテンツの外側に <Authorized> を追加します。名前の通り、認証に成功した場合のみコンテンツが表示されます。さらに、認証に失敗した場合の <NotAuthorized> コードを新たに追加します。ここでは Context="IdentityContext" を忘れずに指定してください。指定しないと Blog の <EditForm> 自体の context と競合します。

次に App.razor で <CascadingAuthenticationState> を使って元の <Router> をラップし、Blazor に対してすべてのコンポーネントが認証を通過する必要があることを伝えます。

続いて NavMenu.razor です。<Authorized> コンポーネントにログアウトリンクを追加し、ログインリンクは <NotAuthorized> に移動します。アイコンも変更します。

ここでシステムを再起動すると認証機構が有効になります。未認証のアクセスが確かにブロックされていることが確認できます。

ログインする前に、Dev Tool の Application タブで Cookies を確認すると、現在は 1 つの Cookie だけです。

ログイン後、新しい Cookie が表示されます。これが Authentication Cookie です。

次にログアウトを試してみます。左側の Logout をクリックしますが、想定通りにはログアウトされず、Log out ページに遷移します。右上はまだログイン状態のままで、Authentication Cookie も残っています。

Logout.cshtml.cs を見てみると、OnGet()(サイト管理者注:.NET 6 Blazor server にはこのメソッドはありません。比較してください)と OnPost() があり、それぞれ HttpGet と HttpPost に対応しています。リンクから遷移するのは HttpGet ですが、OnGet() では何も処理を行っていません。一方 OnPost() では ASP.NET Core Identity API を呼び出してユーザーをログアウトさせます。
原文の画像:OnGet() メソッドが追加されている

サイト管理者の .NET 6 プロジェクトのスクリーンショット:上記と比較して OnGet() メソッドがない

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" が定義されています。

ただし、ログアウト後に Log out ページに留まるのは意味がないので、OnPost() の else ブロックを return LocalRedirect("~/Blog"); に変更します。これにより、ログアウト後は認証されていない Blog ページに戻ります。


これで単一プロジェクトでのログイン認証機構が完成しました。さまざまな機能やページが揃っています。小規模なプロジェクトであればこの方法で構いません。明日はこれらの ASP.NET Core の認証原理について説明します。
参照:
注:本記事のコードは .NET 6 + Visual Studio 2022 でリファクタリングされています。原文と比較しながら学習していただければ幸いです。ご愛読ありがとうございます。原作者を応援してください。