첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
다운로드

▶ 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
반응형
그리드형(광고전용)

'C# > ASP.NET MVC' 카테고리의 다른 글

[C#/ASP.NET MVC/.NETCORE] UseMiddlewareExtensions 클래스 : UseMiddleware 확장 메소드를 사용해 종단 미들웨어 등록하기  (0) 2020.11.16
[C#/ASP.NET MVC/.NETCORE] UseMiddlewareExtensions 클래스 : UseMiddleware 확장 메소드를 사용해 요청 가공 미들웨어 등록하기  (0) 2020.11.16
[C#/ASP.NET MVC/.NETCORE] UseMiddlewareExtensions 클래스 : UseMiddleware 확장 메소드를 사용해 컨텐트 생성 미들웨어 등록하기  (0) 2020.11.16
[C#/ASP.NET MVC/.NETCORE] WebHostBuilderIISExtensions 클래스 : UseIISIntegration 확장 메소드를 사용해 IIS 웹 서버를 역전 프록시로 설정하기  (0) 2020.11.16
[C#/ASP.NET MVC/.NETCORE] HostingAbstractionsWebHostBuilderExtensions 클래스 : UseContentRoot 확장 메소드를 사용해 컨텐트 루트 경로 설정하기  (0) 2020.11.16
[C#/ASP.NET MVC/.NETCORE] Identity 인증 : IdentityUser 객체에 커스텀 관리 항목 추가하기  (0) 2020.11.10
[C#/ASP.NET MVC/.NETCORE] IdentityServer4 액세스 토큰 갱신하기  (0) 2020.11.09
[C#/ASP.NET MVC/.NETCORE] HeaderPropagationApplicationBuilderExtensions 클래스 : UseHeaderPropagation 확장 메소드를 사용해 헤더 전파 미들웨어 추가하기  (0) 2020.11.08
[C#/ASP.NET MVC/.NETCORE] 누겟 설치 : Microsoft.AspNetCore.HeaderPropagation  (0) 2020.11.08
[C#/ASP.NET MVC/.NETCORE] HttpClientBuilderExtensions 클래스 : ConfigurePrimaryHttpMessageHandler 확장 메소드를 사용해 HttpMessageHandler 구성하기  (0) 2020.11.08
Posted by icodebroker

댓글을 달아 주세요