[ASP.NET Blazor Server][MudBlazor] MudBlazorの使い方10

アプリケーションの入り口となる「ログイン画面」を作ってみましょう。

以下の知識が必要になります。

「美しくて使いやすい」ログイン画面にするためには、単に入力欄を並べるだけでなく、「画面の中央に配置されたカード型デザイン」や、「パスワードの表示/非表示を切り替える目のマーク(アイコン)」を実装するのが定番です。

MudBlazorなら、これらを驚くほど少ないコードで実現できます。実際のコードを見てみましょう!

まずは認証の機能がない単純なログイン画面から。次に認証機能ありのログイン画面を示します。


認証無しログイン画面

以下のコードは、画面の中央にログインフォームを配置し、使い勝手を向上させるための工夫を盛り込んだ完全なサンプルです。

@page "/login"
@layout LoginLayout @* もし専用のレイアウトがあれば指定します *@

<MudContainer MaxWidth="MaxWidth.Small" Class="d-flex align-center justify-center" Style="height: 100vh;">
    
    <MudCard Elevation="4" Class="pa-6" Style="width: 100%; max-width: 400px;">
        
        <MudCardHeader Class="d-flex justify-center">
            <MudText Typo="Typo.h4" Color="Color.Primary" Style="font-weight: bold;">アプリへログイン</MudText>
        </MudCardHeader>

        <MudCardContent>
            <MudTextField @bind-Value="_email" 
                          Label="メールアドレス" 
                          Variant="Variant.Outlined" 
                          Margin="Margin.Normal" 
                          Adornment="Adornment.Start" 
                          AdornmentIcon="@Icons.Material.Filled.Email" />

            <MudTextField @bind-Value="_password" 
                          Label="パスワード" 
                          Variant="Variant.Outlined" 
                          Margin="Margin.Normal"
                          InputType="@_passwordInput" 
                          Adornment="Adornment.End" 
                          AdornmentIcon="@_passwordInputIcon" 
                          OnAdornmentClick="TogglePasswordVisibility" />

            <MudCheckBox @bind-Value="_rememberMe" 
                         Label="ログイン状態を保持する" 
                         Color="Color.Primary" 
                         Class="mt-2" />
        </MudCardContent>

        <MudCardActions Class="d-flex flex-column align-center">
            <MudButton Variant="Variant.Filled" 
                       Color="Color.Primary" 
                       Size="Size.Large" 
                       FullWidth="true" 
                       OnClick="SubmitLogin">
                ログイン
            </MudButton>

            <MudButton Variant="Variant.Text" 
                       Color="Color.Default" 
                       Class="mt-4">
                パスワードをお忘れですか?
            </MudButton>
        </MudCardActions>

    </MudCard>
</MudContainer>

@code {
    // ユーザーが入力するデータ
    private string _email = "";
    private string _password = "";
    private bool _rememberMe = false;

    // パスワードの表示・非表示を管理する変数
    private bool _isShowPassword = false;
    private InputType _passwordInput = InputType.Password;
    private string _passwordInputIcon = Icons.Material.Filled.VisibilityOff;

    // 目のアイコンをクリックしたときの処理
    private void TogglePasswordVisibility()
    {
        if (_isShowPassword)
        {
            _isShowPassword = false;
            _passwordInputIcon = Icons.Material.Filled.VisibilityOff; // 斜線ありの目
            _passwordInput = InputType.Password; // 黒丸(●●●)にする
        }
        else
        {
            _isShowPassword = true;
            _passwordInputIcon = Icons.Material.Filled.Visibility; // 普通の目
            _passwordInput = InputType.Text; // 入力された文字をそのまま見せる
        }
    }

    // ログインボタンを押したときの処理
    private void SubmitLogin()
    {
        // ここで「AuthenticationStateProvider」などを呼び出して、
        // データベースのID/パスワードと照合する処理を書きます。
        
        Console.WriteLine($"Email: {_email}, Password: {_password}, Remember: {_rememberMe}");
    }
}

この画面の「使いやすい(ユーザーフレンドリー)」ポイント

  1. アイコンの活用(Adornment): メールアドレス欄の左側(Adornment="Adornment.Start")にメールアイコンを置くことで、何を入力する場所か直感的に伝わります。
  2. パスワードの可視化(TogglePasswordVisibility): パスワード入力欄の右側(Adornment="Adornment.End")に目のアイコンを配置しています。これをクリックすると、C#の処理が走って InputType.Password(黒丸)と InputType.Text(平文)が切り替わり、同時におめめパッチリのアイコンと斜線入りのアイコンが切り替わります。スマホアプリなどでよく見るあの便利な動きが、JavaScriptゼロで作れます。
  3. カードを使った視線誘導: 画面全体(100vh)の中央に MudCard を配置し、わずかな影(Elevation="4")をつけることで、ユーザーの視線を自然に入力フォームへ集中させています。

いよいよUI(見た目)とロジック(中身)を結合する段階ですね!これができると、本格的なWebアプリの動きに一気に近づきます。

Blazorで認証を行う場合、UIのボタンが押されたら、AuthenticationStateProvider という「アプリ全体の認証状態を管理する番人」にデータを渡し、身分証(クレーム)を発行してもらう、という流れになります。

今回は、データベース接続などの複雑なサーバー設定を省き、「Blazor側でどうやってログイン処理を呼び出し、画面を切り替えるのか」という仕組み(フロー)を理解するためのシンプルな実装をご紹介します。

必要なのは以下の3つのファイル(ステップ)です。

認証ありログイン画面


1. 認証ロジックの本体(CustomAuthStateProvider.cs)

まずは、アプリ全体のログイン状態を管理するクラスを新しく作ります。これが「番人」の役割を果たします。

using System.Security.Claims;
using Microsoft.AspNetCore.Components.Authorization;

public class CustomAuthStateProvider : AuthenticationStateProvider
{
    // 現在のユーザー情報(最初は「未ログイン(空っぽ)」の状態)
    private ClaimsPrincipal _currentUser = new(new ClaimsIdentity());

    // Blazorのシステムから「今のログイン状態は?」と聞かれたときに返すメソッド
    public override Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        return Task.FromResult(new AuthenticationState(_currentUser));
    }

    // ログイン処理(Login.razorから呼ばれる)
    public void Login(string email, string password)
    {
        //  本来はここでデータベースやWebAPIに問い合わせてパスワードをチェックします
        // 今回はデモとして、特定のメールとパスワードなら成功とします
        if (email == "test@example.com" && password == "password123")
        {
            // 身分証(Claim)を作成
            var claims = new[]
            {
                new Claim(ClaimTypes.Name, "テストユーザー"),
                new Claim(ClaimTypes.Email, email),
                new Claim(ClaimTypes.Role, "Admin") // 権限(ロール)も付与できる
            };

            // 身分証を持った「ログイン済みユーザー」を作成
            var identity = new ClaimsIdentity(claims, "CustomAuth");
            _currentUser = new ClaimsPrincipal(identity);

            // アプリ全体に「ログイン状態が変わったよ!」とお知らせする
            NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(_currentUser)));
        }
        else
        {
            // 失敗した場合は例外を投げるか、エラーを返す(今回は例外にしています)
            throw new Exception("メールアドレスまたはパスワードが間違っています。");
        }
    }

    // ログアウト処理
    public void Logout()
    {
        _currentUser = new ClaimsPrincipal(new ClaimsIdentity()); // 未ログイン状態に戻す
        NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(_currentUser)));
    }
}

2. UIからロジックを呼び出す(Login.razor)

前回作成したログイン画面の @code ブロックを修正し、先ほど作った番人(CustomAuthStateProvider)を呼び出します。また、成功したら別のページへ移動する処理も追加します。

@page "/login"
@inject AuthenticationStateProvider AuthStateProvider
@inject NavigationManager NavManager
@inject ISnackbar Snackbar

<MudContainer MaxWidth="MaxWidth.Small" Class="d-flex align-center justify-center" Style="height: 100vh;">
    <MudCard Elevation="4" Class="pa-6" Style="width: 100%; max-width: 400px;">
        <MudCardHeader Class="d-flex justify-center">
            <MudText Typo="Typo.h4" Color="Color.Primary" Style="font-weight: bold;">ログイン</MudText>
        </MudCardHeader>

        <MudCardContent>
            <MudTextField @bind-Value="_email" Label="メールアドレス" Variant="Variant.Outlined" Margin="Margin.Normal" />
            <MudTextField @bind-Value="_password" Label="パスワード" Variant="Variant.Outlined" InputType="InputType.Password" Margin="Margin.Normal" />
        </MudCardContent>

        <MudCardActions>
            <MudButton Variant="Variant.Filled" Color="Color.Primary" FullWidth="true" OnClick="SubmitLogin">
                ログイン
            </MudButton>
        </MudCardActions>
    </MudCard>
</MudContainer>

@code {
    private string _email = "";
    private string _password = "";

    private void SubmitLogin()
    {
        try
        {
            // 1. 注入した AuthStateProvider を先ほど作った Custom に変換する
            var customAuth = (CustomAuthStateProvider)AuthStateProvider;

            // 2. ログインロジックを実行!
            customAuth.Login(_email, _password);

            // 3. 成功したら、トップページ("/")へ強制移動する
            Snackbar.Add("ログインに成功しました!", Severity.Success);
            NavManager.NavigateTo("/");
        }
        catch (Exception ex)
        {
            // 失敗したら赤色でエラーメッセージを出す
            Snackbar.Add(ex.Message, Severity.Error);
        }
    }
}

3. アプリの起動設定に登録する(Program.cs)

最後に、「このアプリではさっき作ったカスタム番人を使いますよ」ということを Blazor のシステム(Program.cs)に教えてあげる必要があります。

// Program.cs の builder.Services が並んでいる場所に以下を追加します

// Blazorの認証・認可機能を有効化
builder.Services.AddAuthorizationCore();

// 標準の AuthenticationStateProvider の代わりに、今回作った CustomAuthStateProvider を使うよう登録
builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();

この一連の流れのポイント

  1. ユーザーが Login.razor でボタンを押す。
  2. CustomAuthStateProviderLogin メソッドが呼ばれ、メールとパスワードを検証する。
  3. 成功すると、身分証(ClaimsPrincipal) が作成され、システムに登録される。
  4. NavManager.NavigateTo("/") でトップページへ移動する。
  5. 以降は、他のページで [Authorize] 属性をつけておけば、この身分証を持っているか自動でチェックしてくれるようになる。

これが、BlazorとMudBlazorを組み合わせた認証の基本骨格です。実際の業務では、Loginメソッドの中でデータベースを見に行ったり、外部のAPIから認証トークン(JWTなど)をもらってきたりする処理に置き換えるだけで済みます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする