ユーザー認証機能の実装
ASP.NET coreではユーザー認証の仕組みを自動で生成することができます。
簡単に認証機能を実装できるなら是非とも利用したいので、実際にプロジェクトを作成してどんなコードが生成されるのか確認してみました。
目次
- 認証機能を実装したプロジェクトの作成
- Startup.cs
- appsettings.json
- Data/ApplicationDbContext.cs
- Models/ApplicationUser.cs
- Views/Account/*
- Controllers/AccountController.cs
- 実際の画面
- 最後に
- 参考リンク
認証機能を実装したプロジェクトの作成
Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
}
}
options.UseSqlServer()で認証で利用するSQLServerのDBを指定しています。
EntityFrameworkのコードファーストが前提となるようなので、個人的にはSQLServer以外でちゃんと動作するのか...という不安があります。
appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-WebApplication9-**********;Trusted_Connection=True;MultipleActiveResultSets=true"
},
}
デフォルトのDB接続文字列が「appsettings.json」に設定されています。
Data/ApplicationDbContext.cs
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
認証で利用するテーブル名の変更など、カスタマイズしたい場合に利用します。
Models/ApplicationUser.cs
public class ApplicationUser : IdentityUser
{
}
ユーザー情報で追加したいプロパティがあればここに追記します。
Views/Account/*
Controllers/AccountController.cs
認証関連のコントローラー。とりあえずログイン(Login)とユーザー登録(Register)のみ抜粋。
[Authorize]
[Route("[controller]/[action]")]
public class AccountController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
public AccountController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
{
_userManager = userManager;
_signInManager = signInManager;
}
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Login(string returnUrl = null)
{
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return RedirectToLocal(returnUrl);
}
}
return View(model);
}
[HttpGet]
[AllowAnonymous]
public IActionResult Register(string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme);
await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl);
await _signInManager.SignInAsync(user, isPersistent: false);
return RedirectToLocal(returnUrl);
}
}
return View(model);
}
}
実際の画面
最後に
とりあえずは個人で利用すると思いますので、こんなに立派な機能はいらないですね。必要なものだけに絞り込んで使ってみます。