[C#/ASP.NET MVC/.NETCORE] Identity 인증 : IdentityUser 객체에 커스텀 관리 항목 추가하기 (SQL SERVER 사용)
C#/ASP.NET MVC 2020. 11. 10. 16:15728x90
반응형
728x170
▶ TestProject.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.0" />
<PackageReference Include="NETCore.MailKit" Version="2.0.3" />
</ItemGroup>
<ItemGroup>
<Folder Include="Migrations\" />
</ItemGroup>
</Project>
728x90
▶ appsettings.json
{
"MailAddress" :
{
"Server" : "smtp.live.com",
"Port" : 587,
"SenderName" : "sender",
"SenderEmail" : "sender@hotmail.com",
"Account" : "sender@hotmail.com",
"Password" : "password",
"Security" : true
},
"Logging" :
{
"LogLevel" :
{
"Default" : "Information",
"Microsoft" : "Warning",
"Microsoft.Hosting.Lifetime" : "Information"
}
},
"AllowedHosts" : "*",
"ConnectionStrings" :
{
"DefaultConnection" : "Server=(localdb)\\MSSQLLocalDB;Database=TestDB;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
300x250
▶ Data/DatabaseContext.cs
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using TestProject.Models;
namespace TestProject.Data
{
/// <summary>
/// 데이터베이스 컨텍스트
/// </summary>
public class DatabaseContext : IdentityDbContext<ApplicationUser>
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - DatabaseContext(options)
/// <summary>
/// 생성자
/// </summary>
/// <param name="options">옵션</param>
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
{
}
#endregion
}
}
▶ Models/ApplicationUser.cs
using Microsoft.AspNetCore.Identity;
namespace TestProject.Models
{
/// <summary>
/// 애플리케이션 사용자
/// </summary>
public class ApplicationUser : IdentityUser
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 부서 - Department
/// <summary>
/// 부서
/// </summary>
public string Department { get; set; }
#endregion
}
}
▶ Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NETCore.MailKit.Extensions;
using NETCore.MailKit.Infrastructure.Internal;
using TestProject.Data;
using TestProject.Models;
namespace TestProject
{
/// <summary>
/// 시작
/// </summary>
public class Startup
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 구성
/// </summary>
private IConfiguration configuration;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - Startup(configuration)
/// <summary>
/// 생성자
/// </summary>
/// <param name="configuration">구성</param>
public Startup(IConfiguration configuration)
{
this.configuration = configuration;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 서비스 컬렉션 구성하기 - ConfigureServices(services)
/// <summary>
/// 서비스 컬렉션 구성하기
/// </summary>
/// <param name="services">서비스 컬렉션</param>
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DatabaseContext>
(
options =>
{
options.UseSqlServer(this.configuration["ConnectionStrings:DefaultConnection"]);
}
);
services.AddIdentity<ApplicationUser, IdentityRole>
(
options =>
{
options.Password.RequiredLength = 4;
options.Password.RequireDigit = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.SignIn.RequireConfirmedEmail = true;
}
)
.AddEntityFrameworkStores<DatabaseContext>()
.AddDefaultTokenProviders();
services.ConfigureApplicationCookie
(
options =>
{
options.Cookie.Name = "TestCookie";
options.LoginPath = "/Home/Login";
}
);
services.AddMailKit
(
options =>
{
options.UseMailKit(this.configuration.GetSection("MailAddress").Get<MailKitOptions>());
}
);
services.AddControllersWithViews();
}
#endregion
#region 구성하기 - Configure(app, environment)
/// <summary>
/// 구성하기
/// </summary>
/// <param name="app">애플리케이션 빌더</param>
/// <param name="environment">웹 호스트 환경</param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment environment)
{
if(environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints
(
endpoints =>
{
endpoints.MapDefaultControllerRoute();
}
);
}
#endregion
}
}
▶ Controllers/HomeController.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using NETCore.MailKit.Core;
using TestProject.Models;
namespace TestProject.Controllers
{
/// <summary>
/// 홈 컨트롤러
/// </summary>
public class HomeController : Controller
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 사용자 관리자
/// </summary>
private readonly UserManager<ApplicationUser> userManager;
/// <summary>
/// 서명 관리자
/// </summary>
private readonly SignInManager<ApplicationUser> signInManager;
/// <summary>
/// E 메일 서비스
/// </summary>
private readonly IEmailService emailService;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - HomeController(userManager, signInManager, emailService)
/// <summary>
/// 생성자
/// </summary>
/// <param name="userManager">사용자 관리자</param>
/// <param name="signInManager">서명 관리자</param>
/// <param name="emailService">E 메일 서비스</param>
public HomeController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager, IEmailService emailService)
{
this.userManager = userManager;
this.signInManager = signInManager;
this.emailService = emailService;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 인덱스 페이지 처리하기 - Index()
/// <summary>
/// 인덱스 페이지 처리하기
/// </summary>
/// <returns>액션 결과</returns>
public IActionResult Index()
{
return View();
}
#endregion
#region 비밀 페이지 처리하기 - Secret()
/// <summary>
/// 비밀 페이지 처리하기
/// </summary>
/// <returns>액션 결과</returns>
[Authorize]
public IActionResult Secret()
{
return View();
}
#endregion
#region 로그인 페이지 처리하기 - Login()
/// <summary>
/// 로그인 페이지 처리하기
/// </summary>
/// <returns>액션 결과</returns>
[HttpGet]
public IActionResult Login()
{
return View();
}
#endregion
#region 로그인 페이지 처리하기 - Login(userName, password)
/// <summary>
/// 로그인 페이지 처리하기
/// </summary>
/// <param name="userName">사용자명</param>
/// <param name="password">패스워드</param>
/// <returns>액션 결과 태스크</returns>
[HttpPost]
public async Task<IActionResult> Login(string userName, string password)
{
ApplicationUser applicationUser = await this.userManager.FindByNameAsync(userName);
if(applicationUser != null)
{
Microsoft.AspNetCore.Identity.SignInResult signInResult = await this.signInManager.PasswordSignInAsync
(
applicationUser,
password,
false,
false
);
if(signInResult.Succeeded)
{
return RedirectToAction("Index");
}
}
return RedirectToAction("Index");
}
#endregion
#region 등록 페이지 처리하기 - Register()
/// <summary>
/// 등록 페이지 처리하기
/// </summary>
/// <returns>액션 결과</returns>
[HttpGet]
public IActionResult Register()
{
return View();
}
#endregion
#region 등록 페이지 처리하기 - Register(userName, password, mailAddress, department)
/// <summary>
/// 등록 페이지 처리하기
/// </summary>
/// <param name="userName">사용자명</param>
/// <param name="password">패스워드</param>
/// <param name="mailAddress">메일 주소</param>
/// <param name="department">부서</param>
/// <returns>액션 결과 태스크</returns>
[HttpPost]
public async Task<IActionResult> Register(string userName, string password, string mailAddress, string department)
{
ApplicationUser applicationUser = new ApplicationUser
{
UserName = userName,
Email = mailAddress,
Department = department
};
IdentityResult result = await this.userManager.CreateAsync(applicationUser, password);
if(result.Succeeded)
{
string code = await this.userManager.GenerateEmailConfirmationTokenAsync(applicationUser);
var link = Url.Action
(
"ConfirmMailAddress",
"Home",
new { userID = applicationUser.Id, code },
Request.Scheme,
Request.Host.ToString()
);
await this.emailService.SendAsync
(
mailAddress,
"메일 주소 확인 요청",
$"<a href=\"{link}\">메일 주소 확인</a>",
true
);
return RedirectToAction("SendMailNotification");
}
return RedirectToAction("Index");
}
#endregion
#region 메일 발송 통지 페이지 처리하기 - SendMailNotification()
/// <summary>
/// 메일 발송 통지 페이지 처리하기
/// </summary>
/// <returns>액션 결과</returns>
public IActionResult SendMailNotification()
{
return View();
}
#endregion
#region 메일 주소 확인 페이지 처리하기 - ConfirmMailAddress(userID, code)
/// <summary>
/// 메일 주소 확인 페이지 처리하기
/// </summary>
/// <param name="userID">사용자 ID</param>
/// <param name="code">코드</param>
/// <returns>액션 결과 태스크</returns>
public async Task<IActionResult> ConfirmMailAddress(string userID, string code)
{
ApplicationUser applicationUser = await this.userManager.FindByIdAsync(userID);
if(applicationUser == null)
{
return BadRequest();
}
IdentityResult identityResult = await this.userManager.ConfirmEmailAsync(applicationUser, code);
if(identityResult.Succeeded)
{
return View();
}
return BadRequest();
}
#endregion
#region 로그아웃 페이지 처리하기 - LogOut()
/// <summary>
/// 로그아웃 페이지 처리하기
/// </summary>
/// <returns>액션 결과 태스크</returns>
public async Task<IActionResult> LogOut()
{
await this.signInManager.SignOutAsync();
return RedirectToAction("Index");
}
#endregion
}
}
▶ Views/Home/Register.cshtml
<h1>등록 페이지</h1>
<hr />
<form action="/Home/Register" method="post">
<table>
<tr>
<td>사용자명</td>
<td><input type="text" name="userName" value="" /></td>
</tr>
<tr>
<td>패스워드</td>
<td><input type="password" name="password" value="" /></td>
</tr>
<tr>
<td>메일 주소</td>
<td><input type="text" name="mailAddress" value="" /></td>
</tr>
<tr>
<td>부서</td>
<td><input type="text" name="department" value="" /></td>
</tr>
</table>
<button type="submit">등록</button>
</form>
▶ Views/Home/Login.cshtml
<h1>로그인 페이지</h1>
<hr />
<form action="/Home/Login" method="post">
사용자명 : <input type="text" name="userName" value="" /><br />
패스워드 : <input type="text" name="password" value="" /><br />
<button type="submit">로그인</button>
</form>
728x90
반응형
그리드형(광고전용)
댓글을 달아 주세요