Web Programming/ASP .Net Core 3

[Asp.net core MVC] 쿠키와 세션을 이용한 로그인 구현

안녕하세요, 씨앤텍시스템즈 황순호 연구원입니다.

 

이번 포스트는 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

 

ASP.NET Core Middleware

Learn about ASP.NET Core middleware and the request pipeline.

docs.microsoft.com

 

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에서 쿠키와 세션을 이용한 로그인 구현에 대해 작성하였습니다.

감사합니다.

728x90

'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