ASP.NET Identityを使うと簡単にユーザー認証の仕組みが追加できます。
でも、標準では下の画面のように電子メール(アカウントIDになる)とパスワードしかありません。「必要な項目があれば自分でカスタマイズしてね」って事ですね。
そんなわけで、カスタマイズする方法をちょこっと書いておこうと思います。
といっても、EntityFrameworkを知ってたら大した話ではないんですけどね。
このエントリでは氏名を登録する項目を追加してみることにします。
マイグレーションを有効にする
※この作業はプロジェクトを作成直後のようにデータベースが作成されていない状態では不要です。
パッケージマネージャコンソールから以下のコマンドを実行します。
PM> Enable-Migrations
Modelの変更
プロパティを追加する
ApplicationUser クラスに Name プロパティを追加します。
public class ApplicationUser : IdentityUser { public string Name { get; set; }
データベースをマイグレーションする
※この作業はプロジェクトを作成直後のようにデータベースが作成されていない状態では不要です。
パッケージマネージャコンソールから以下のコマンドを実行します。
PM> Add-Migration AddNamePropertyToApplicationUser PM> Update-Database
これで AspNetUsers テーブルに Name という項目が追加されました。
ViewModelの変更
View とやりとりするための ViewModel を変更します。
ユーザー登録の画面に項目を追加したいので、RegisterViewModel クラスに Name プロパティを追加します。
public class RegisterViewModel { [Required] [Display(Name = "氏名")] public string Name { get; set; } [Required] [EmailAddress] [Display(Name = "電子メール")] public string Email { get; set; } // ~以下略~
Viewの変更
Register.cshtml に RegisterViewModel に追加した Name プロパティと連携するためのコードを追加します。
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { @Html.AntiForgeryToken() <h4>新しいアカウントを作成します。</h4> <hr /> @Html.ValidationSummary("", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(m => m.Name, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.Name, new { @class = "form-control" }) </div> </div> <div class="form-group"> @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) </div> </div> // ~以下略~
Controllerの変更
ViewからPOSTされたデータを元に、ユーザーを作成している AccountController クラスの Register メソッドを修正します。ApplicationUser クラスの Name プロパティに RegisterViewModel の Name プロパティをセットしましょう。
// POST: /Account/Register [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new ApplicationUser { UserName = model.Email, Email = model.Email, Name = model.Name }; var result = await UserManager.CreateAsync(user, model.Password); // ~以下略~
おしまい
これでユーザー登録時に氏名を登録できるようになりました。
Twitter等の外部認証を行っている場合には、下記処理にも同様な処置を行っておきましょう。
- ExternalLoginConfirmationViewModel クラスに Name プロパティ追加
- ExternalLoginConfirmation.cshtml に入力項目追加
- AccountController クラスの ExternalLoginConfirmation メソッドで ApplicationUser クラスの Name プロパティセット
おまけ
今回は手動でマイグレーションしましたけど、面倒くさいとか、開発途中でモデルがコロコロ変わる場合には自動マイグレーションの設定をしておけばいいと思います。
以下のような感じでいいと思います。
マイグレーションを有効にしてない場合
最初にパッケージマネージャコンソールで以下のように「-Auto」オプションを付けます。
PM> Enable-Migrations -Auto
マイグレーションを有効にしてしまってる場合
Configuration クラスのコンストラクタで、AutomaticMigrationsEnabled を true にします。
internal sealed class Configuration : DbMigrationsConfiguration<WebApplication9.Models.ApplicationDbContext> { public Configuration() { AutomaticMigrationsEnabled = true; // ~以下略~
データベースのイニシャライザを指定する
Startup クラスでイニシャライザを指定します。
public partial class Startup { public void Configuration(IAppBuilder app) { Database.SetInitializer(new MigrateDatabaseToLatestVersion<ApplicationDbContext,Configuration>()); ConfigureAuth(app); } }