ASP.NET Core フレームワークを用いて文献管理システムを作る 【第4回 Identity のカスタマイズ1】

1. 前回のあらすじ

前回はIdentity 認証ページの日本語化を行いました。日本語化を行うにはスキャフォールディングを追加し、Identity に関する View を導入することで、表示部分を変更できました。また、入力フォームは各 View の中に含まれている .cs ファイルが制御しています。入力フォームに対応する部分に

[Display(Name = "表示したい名前")]

を入力すれば、フォームのラベル名 (表示名) を変えることができました。

2. 新たな問題点と目標

現状では何も不自由ないシステムですが、ローカルで動かすにはパスワードの制約が厳重過ぎます。セキュリティ面を考えれば問題ありませんが、パスワードに小文字・大文字・記号・6文字以上という制約はちょっと面倒ですね。加えて、メールアドレスがユーザ名になるのは個人的には嫌なので、入力フォームをいろいろカスタマイズしていきたいと思います。今回の目標は以下の通りです。

  1. パスワードの制約を変更
  2. 入力フォームに "ユーザ名" を追加

3. Identity パスワードの制約をカスタマイズする

Identity のパスワードに関するオプションはプロジェクトディレクトリにある Startup.cs にて変更します。ここにはWebアプリに関する設定やサービスなどを制御するためのコードが書かれています。Identity パスワードのデフォルト設定値は次の通りです。

プロパティ 意味 デフォルトの設定
RequiredLength パスワードの最低文字数 6
RequireDigit パスワードに数字 (0~9) を含める true
RequireLowercase パスワードに小文字を含める true
RequireUppercase パスワードに大文字を含める true
RequireNonAlphanumeric パスワードに英数字以外の文字を含める true
RequiredUniqueChars 文字の種類の最低構成 1

デフォルトのままではパスワードの制約が結構あるので、いくつか修正していきます。修正したいものをリストアップします。リストにないものは変更なしです。

修正するプロパティ 修正前 修正後
RequiredLength 6 4
RequireDigit true false
RequireUppercase true false
RequireNonAlphanumeric true false

このように設定すれば、パスワードは最低4文字で小文字だけで構成できます。デバッグ用には問題ない設定だと思います。(もちろん、セキュリティ面を考えてより厳しくしてもいいです。) 他にも、ログインに失敗した際のロックアウト設定もできますが、今回はいじりません。

実際にコーディングしていきます。Startup.cs のソースコードに ConfigureServices メソッドがあるので、そのメソッド内にIdentityオプションプロパティを追記します。既に他のサービスオプションが記述されているので、その次の行に付け足します。

public void ConfigureServices(IServiceCollection services)
{
     // 既に書かれている設定 (サービス)
     // ここにオプションを追記
}

オプション追記後

public void ConfigureServices(IServiceCollection services)
{
     //既に書かれている設定 (サービス)
     services.Configure<IdentityOptions>(options =>
     {
           // パスワードの設定
           options.Password.RequireDigit = false;
           options.Password.RequireLowercase = true;
           options.Password.RequireNonAlphanumeric = false;
           options.Password.RequireUppercase = false;
           options.Password.RequiredLength = 4;
           options.Password.RequiredUniqueChars = 1;
       });
}

これでパスワードの設定ができました。

4. 新規登録画面にてユーザ名入力フォームを作成する

次に、ユーザ名を入力できるフォームを作ります。デフォルトではメールアドレスがユーザ名になってしまうので、他人にメールアドレスを見られてしまいます。あとダサいです(笑)。
まずは Identity の View にて Register.cshtml.cs を開き、 InputModel クラスを探します。その中にユーザ名入力フォームを記述します。

public class InputModel
{
     //メアドやパスワードの入力フォームなどが記述されている
     //ここにユーザ名入力フォームを追記
}

追記後

public class InputModel
{
     //メアドやパスワードの入力フォームなどが記述されている
     [Required]
     [StringLength(50, ErrorMessage = "{0} は少なくとも {2} 文字以上 {1} 文字以下で入力してください。", MinimumLength = 4)]
     [DataType(DataType.Text)]
     [Display(Name = "ユーザ名")]
     public string Username { get; set; }
}

ここで、アノテーションについて解説します。アノテーションは属性ともいい、フォームに対するルールを付属させることができます。記述する際には [ ] で囲みます。username は入力された文字を保持しておく変数です。これを後ほどデータベースにバインドします。

アノテーション 意味
Required 入力を必須にする
StringLength 最大入力文字数を指定する
DataType 扱うデータの種類を指定する
Display フォームのラベル (表示名) を指定する

4.1 Required

入力必須フォームにするためのアノテーションです。これ以上説明しようがないのですが、付け足すとすれば NULL を禁止にするという意味があります。NULL状態 (空欄状態) を受け付けたくないときに設定します。

4.2 StringLength

最大文字数を指定できますが、パラメータを指定すれば最小文字数も変更可能です。( ) の中には 50, ErrorMessage, MinimumLength の3つのパラメータが入っています。50は最大文字数、ErrorMessageはエラーの表示内容、MinimumLengthは最小文字数を表しています。
ErrorMessage に {0}, {1}, {2} がありますが、{0} = フォーム名、{1} = 最大文字数、{2} = 最小文字数 のパラメータが表示されます。

4.3 DataType

フォームで扱うデータの種類を指定できます。( ) の中に DataType.フィールド名 を指定します。

フィールド名 意味
Text 文字列 (テキスト) を扱う
EmailAddress メールアドレスを扱う (@マークを識別)
Date 日付を扱う (年、月、日を区別する)
Password パスワードを扱う (入力文字が表示されない)

この他にもありますが省略します。あとは調べてみてください。

4.4 Display

前回でてきた魔法のコードです。 入力フォームの表示名を変更することができます。( Name = "表示名" ) をパラメータとして反映させます。

5. 入力フォームを View に表示する

.cs ファイルはあくまでもロジック (動作) 部分を変更しただけなので、ページには表示されていません。なので作成した入力フォームを View にて表示させます。Register.cshtml を開くとHTMLで色々と記述されていますが、

で囲まれている要素の間に次のようなコードを挿入します。

<div class="form-group">
     <label asp-for="Input.Username"></label>
     <input asp-for="Input.Username" class="form-control" />
     <span asp-validation-for="Input.Username" class="text-danger" />
</div>

挿入後 f:id:takunology:20190621162341j:plain

分かりづらいと思ったのでまるごとスクショしてみました。これで View から InputModel へ受け渡され、Controller によってデータベースへ反映されます。実際に実行してみましょう。 f:id:takunology:20190621162711p:plain

無事に表示されました。これで登録してみましょう。 f:id:takunology:20190621163007j:plain

はい、ユーザ名がメールアドレスのままですね。原因は username がデータベースに反映されてないのが問題です。これを設定したいのですが、ブログが長くなってしまうので次回にします。

5. まとめ

Identity のパスワードのカスタマイズは Startup.cs の 中に記述していきます。プロパティでは特定文字を含める・文字数の設定などを行えます。
フォームは View とその ロジック側で変更することで反映されます。先にロジック側でフォームの宣言を行ってから VIew で表示できるようにしたほうが良いと思います。