안녕하세요, 씨앤텍시스템즈 황순호 연구원입니다.
이번 포스트는 ASP.NET CORE MVC 5.0에서 쿠키와 세션을 이용한 로그인과 그에 따른 접근 권한을 부여하는 방법까지 작성하도록 하겠습니다.
1. Startup.cs 미들웨어 추가
1-1. Configure 메서드에 다음 내용을 추가합니다.
app.UseAuthentication();
app.UseAuthorization();
app.UseCookiePolicy();
app.UseSession();
미들웨어를 등록할 때 순서를 신경 쓰도록 합니다.
위 미들웨어는 UseRouting()와 UseEndpoints() 사이에 위치해야 하고 UseAuthentication()이 UseAuthorization()보다 먼저 위치하도록 작성합니다.
미들웨어 등록 순서에 대한 내용은 아래 마이크로소프트 문서에서 확인 가능합니다.
ASP.NET Core Middleware | Microsoft Docs
1-2. ConfigureServices 메서드에 다음 내용을 추가합니다.
services.AddAuthentication("Cookies").AddCookie("Cookies", config =>
{
config.ExpireTimeSpan = TimeSpan.FromHours(12);
config.LoginPath = "/Home/Login";
config.LogoutPath = "/Home/Logout";
config.Cookie.Name = "Test.Cookie";
});
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromHours(12);
});
쿠키 만료시간과 세션 만료시간 모두 12시간으로 설정하였습니다.
2. HomeController.cs 내용 작성
2-1. Cookie 발급
컨트롤러에 다음 라이브러리를 호출합니다.
using Newtonsoft.Json;
using System.Text.Json;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
Json형식의 데이터를 변환할 때 Newtonsoft.Json을 이용하고 있는데 해당 라이브러리는 Nuget으로 설치 후 사용 가능합니다.
Home 컨트롤러의 Login 액션에서 Cookie를 발급하도록 내용을 작성합니다.
public IActionResult Login()
{
return View();
}
public IActionResult Login([FromBody] JsonElement p_info)
{
Dictionary<string, string> user = JsonConvert.DeserializeObject<Dictionary<string, string>>(p_info.ToString());
Boolean chk = Check_User(user["ID"], user["PW"]);
ClaimsIdentity identity = null;
bool isAuthenticated = false;
if (chk)
{
HttpContext.Session.SetString("username", user["ID"]);
if (Check_Admin())
{
identity = new ClaimsIdentity(new[] {
new Claim(ClaimTypes.Name, user["ID"]),
new Claim(ClaimTypes.Role, "Admin")
}, CookieAuthenticationDefaults.AuthenticationScheme);
isAuthenticated = true;
}
else
{
identity = new ClaimsIdentity(new[] {
new Claim(ClaimTypes.Name, user["ID"]),
new Claim(ClaimTypes.Role, "User")
}, CookieAuthenticationDefaults.AuthenticationScheme);
isAuthenticated = true;
}
}
if (isAuthenticated)
{
var principal = new ClaimsPrincipal(identity);
var login = HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
return RedirectToAction("Success");
}
return RedirectToAction("Fail");
}
Check_User()와 Check_Admin()은 별도로 작성된 메서드로
Check_User()는 아이디와 패스워드가 일치하는지 DB 조회 후 true 또는 false를 반환하는 코드가 포함되어 있습니다.
Check_Admin()은 세션에 저장된 username을 이용하여 DB 조회 후 Admin 여부를 판별하여 true 또는 false를 반환하는 코드가 포함되어 있습니다.
2-2. Cookie 제거
접근 권한에 사용될 쿠키를 제거함으로써 로그아웃 기능을 수행할 수 있습니다.
public IActionResult Logout()
{
var login = HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return RedirectToAction("Login");
}
3. 접근 권한 설정
로그인 사용자만 접근할 수 있도록 메서드 위에 필터를 추가하여 접근 권한을 설정할 수 있습니다.
[Authorize]
public IActionResult GetSomething()
{
...
}
컨트롤러 전체에 적용할 수도 있으며 ClaimType에 따라 권한을 나눌 수 있습니다.
using Microsoft.AspNetCore.Authorization;
[Authorize(Roles = "Admin")]
public class SomethingController : Controller
{
...
}
4. 세션에서 값 가져오기
4-1. 컨트롤러에서 세션 값 접근
이용자를 구분하기 위해 컨트롤러에선 다음과 같이 값을 곧바로 가져올 수 있습니다.
HttpContext.Session.GetString("username");
다만 컨트롤러외 다른 클래스에서 세션에 접근하기 위해선 추가 설정이 필요합니다.
4-2. 기타 클래스에서 세션 값 접근
Startup.cs의 ConfigureServices 메서드에 다음 코드를 추가합니다.
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
세션 값에 접근하려고 하는 클래스에 다음과 같은 방법으로 값을 가져옵니다.
using Microsoft.AspNetCore.Http;
...
HttpContextAccessor _Ac = new HttpContextAccessor();
string ID = _Ac.HttpContext.Session.GetString("username");
5. 세션 연결 체크
클라이언트와의 연결이 끊어진 경우 로그인페이지로 되돌리기 위해 CheckSession.cs을 생성 후 내용을 작성합니다.
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Routing;
namespace Test
{
public class CheckSession : ActionFilterAttribute, IActionFilter
{
public override void OnActionExecuting(ActionExecutingContext context)
{
var check = context.HttpContext;
if (check.Session.GetString("username") == null)
{
context.Result = new RedirectToRouteResult(new RouteValueDictionary(new { action = "Home", controller = "Login" }));
}
}
}
}
이후 컨트롤러에 필터를 적용합니다.
[Authorize]
[CheckSession]
public class SomethingController : Controller
{
...
}
지금까지 .net core mvc에서 쿠키와 세션을 이용한 로그인 구현에 대해 작성하였습니다.
감사합니다.
'Web Programming > ASP .Net Core 3' 카테고리의 다른 글
SignalR (0) | 2021.03.16 |
---|---|
ASP.Net Core 3.1 과 Nginx 연동 (0) | 2020.11.18 |
ASP .Net Core 3.1 Apache 연동 (0) | 2020.08.18 |
ASP .Net Core 3.1 - MySQL 사용 (4) | 2020.06.03 |
ASP .Net Core 3.1 - Razor (0) | 2020.04.23 |