센로그
12. Authentication 본문
◆ Authentication
인증과 관련된 이야기를 해보자.
우선 Authentication과 Authroization을 구분해야 한다.
인증 vs 권한
- Authentication(인증)
- ex) 가입한 유저인지 아닌지 인증
- Authorization(권한)
- ex) 일반유저인지 운영자인지에 따른 권한 부여
ASP.NET Core 인증에서는 기본 용어 두가지가 등장한다
- Principal: 사용자
- Claim: 사용자(Principal)에 대한 세부 정보들
- 이메일, 이름, 생일, admin 권한 등
우리가 사용하고있는 ASP.NET Core 서버는 내부적으로 Kestrel로 구현되어있다.
Kestrel 서버는 Request가 올 때마다 HttpContext를 생성해준다.
- 여기에 요청과 관련된 모든 정보들이 들어가게 됨. (요청을 한 사용자에 대한 정보 포함)
- HttpContext.User : 현재 사용자(Principal) 확인
- Default 상태로는 익명 + Unauthenticated + 0개의 Claim
- 어떤 정보들이 들어가는지 찾아보면 사용하기 편할 것이다.
https://learn.microsoft.com/ko-kr/aspnet/core/fundamentals/use-http-context?view=aspnetcore-8.0
- HttpContext.User : 현재 사용자(Principal) 확인
ASP.NET Core에서 HttpContext 사용
ASP.NET Core에서 HttpContext를 사용하는 방법.
learn.microsoft.com
Authentication 진행 과정
ASP.NET Core MVC의 인증을 살펴보기 전에, 우선 일반적인 웹 서버에서 인증을 위해 어떤 과정이 필요한지 생각해보자
일반적인 웹 서버에서 인증 과정은 다음과 같다.
- 사용자가 identifier(아이디) 및 secret(비밀번호) 전송
- 전송된 정보가 맞는 정보인지 웹 서버가 확인
- DB에 저장된 정보와 비교
- 정보가 맞다면 사용자의 인증 정보 생성
그러면 ASP.NET Core MVC에서는 어떤 과정으로 진행될까?
다음 과정으로 진행된다.
- 처음에 요청을 보낸 상태에서는, HttpContext.User가 무인증 상태의 익명 사용자 Principal로 채워지게 될 것임. (디폴트)
- 인증을 처리하는 컨트롤러(ex: LoginController)로 id및 secret을 전송
- 매니저 서비스(ex: SignManager)를 이용해서 DB로부터 사용자의 정보를 갖고와서 확인해줌
- 정보가 맞다면 HttpContext.User = new ClaimPrincipal로 교체
- 새 Principal에 알맞는 Claim을 붙여줌
Cookie
그런데 매번 접속할 때마다 새로 인증과정을 거쳐야 한다면 굉장히 불편할 것.
따라서 웹서버의 경우 쿠키를 통해 암호화된 인증 정보를 저장하곤 한다.
- 인증 정보를 쿠키로 저장해두면, 다음 요청부터는 이를 통해 내가 이미 인증받은 사용자라는 걸 알려줄 수 있다.
ASP.NET Core에서도 비슷한 동작을 할 수 있다.
- 새 Principal을 만들어준 다음에, 사용자한테 쿠키 정보를 전송해줄 수 있다.
- 첫 인증때는 앞서 언급한 인증 과정을 따른다.
- 재접속시 Request에 쿠키가 포함되어 있을테니, 쿠키를 찾아서 쿠키가 정상적인지 체크하고 Ok해준다.
Token
이렇듯 쿠키를 통해 인증하는 것도 나쁘진 않은데, 살짝 까다로운 상황이 발생할 수도 있음.
- WebAPI의 경우, 기능별로 서버를 분리하는 경우가 많다.
- 그러나 쿠키는 단일 도메인에서만 유효한 것으로, 다른 서버로 넘어가면 사용할 수 없어서 좀 애매해짐!!
그럼 어떤 대안이 있을까?
- 토큰
- 중앙에서 토큰을 관리하고, 서버들 사이에서도 통용될 수 있도록 하는 방식
ASP.NET Core Identity
그런데 이런 인증들을 직접 구현하는 것은 살짝 위험할 수 있다.
인증 절차에는 유저의 비밀번호, 계정 등 민감한 정보가 많이 오갈것이기 때문.
그래서 우리가 사용할 것은 ASP.NET Core Identity 이다.
몇가지 편한 기능이 포함되어 있다.
- User 및 Claim에 관련된 DB 생성 및 관리
- Password Validation
- User Account Lock (BruteForce Attack)
- 너무 짧은 시간 내에 많은 시도를 하면 일정 시간동안 계정을 lock하는 기능
- 2FA (Two Factor Authentication)
- SNS 인증 기능
- Password Reset
- 비번 분실 시 임시 비번을 만들어주는 기능
- 3rd Party Library
- Facebook, Google 등 연동 기능
Identity 실습
Identity 실습을 해보자.
새로 플젝 하나를 판다. (인증 유형: 개별 계정)
- 인증 유형을 개별 계정으로 하면, Identity가 포함된 버전으로 만들어진다.
어떤 게 달라졌는지 간단히 살펴보자.
- DB에 접속하는 EF Core 부분
- 어떤 DB를 사용할지 지정되어 있음
- 실행해보면, 우측 상단에 Register와 Login이 추가되어있다.
- 각각 클릭하면 실제로 등록하고 로그인할 수 있는 페이지가 뜬다.
근데 이상한 점이 있다.
Register 및 Login의 경우 url이 각각 Identity/Account/Register, Identity/Account/Login 이었는데,
플젝의 뷰를 찾아보면 얘네에 관한 페이지는 찾을 수 없다...!?
=> 얘네는 내부적으로 숨겨져있기 때문.
우리가 커스텀하고 싶은 경우, 직접 꺼내서 작업해야 한다. (스캐폴딩)
Identity 실습 - 스캐폴딩
스캐폴드(꺼내서 작업)하려면 이렇게 하면 된다.
- Identity를 볼 수 있도록 하겠다는 의미
- Identity와 관련하여, 재정의할 파일을 선택한다. (보이게 해서 수정할 수 있도록 할 파일)
이렇게 하면 선택한 파일이 이제 프로젝트에서 볼 수 있도록 설정된다.
- Login 및 Register 파일이 생겼다~
Identity 실습 - Login.cshtml, Register.cshtml
Login.chstml과 Register.cshtml을 자세히 보면, 각각 Login.cshtml.cs와 Register.cshtml.cs가 포함되어있다.
- 얘네는 Razor Pages 방식이다.
- 라우팅 방법은 폴더의 순서 이름을 따라 진행된다.
- Identity/Account/Register 이런 식.
- Program.cs에 보면 app.MapRazorPages(); 라는 한줄이 더 추가되어 있을 것임.
모델 바인딩 방식이 살짝 다른데, [BindProperty] 애트리뷰틀를 사용하고, cshtml에서 태그헬퍼를 사용해 매핑할 C# 변수를 연결해주고 있다.
실행해보면, 실제로 웹에서 입력한 내용과 바인딩됨을 확인할 수 있다.
물론 어디까지나 MVC 방식에서 위와 같이 동작하고 있다는 것임.
- 만약 웹서버를 게임에서 인증하는 목적으로 사용하게 되면, 웹을 기반으로 하기는 하되 클라이언트 쪽에서는 데이터를 json으로 보내주지, 위와 같이 브라우저를 통해서 받지는 않을 것. 즉 기본 identity를 그대로 사용하지는 않을 것이다.
- 하지만 cshtml.cs 쪽에 있는 기능들은 그대로 사용해도 될것임 ㅇㅇ
Identity - DB 구성
또 알아둬야 할 것이 있다.
identity에서 DB 구성에 관한 내용이다.
SQL 서버 개체 탐색기를 살펴보자.
- __EFMigrationHistory
- EF Core의 Migration 버전을 관리한다.
- AspNetUsers
- 핵심 user 정보를 관리한다.
- AspNetUserClaims
- 추가 정보를 관리
- id/pw 뿐만아니라 추천자까지 받고 싶은 경우
- 추가 정보를 관리
- AspNetUserLogins / AspNetUserTokens
- 3rd Party (구글 로그인 등) 관리
- AspNetRoles, AspNetRoleClaims, AspNetUserRoles
- Role 기반의 인증을 해주는 기능들.
- 요즘은 대부분 Claim으로 하니까 잘 안씀. (legacy)
예전 버전들과의 호환을 위해 아직 존재함
'게임 > ASP.NET Core' 카테고리의 다른 글
14. Logging (0) | 2024.04.15 |
---|---|
13. Authorization (0) | 2024.04.15 |
11. Filter (0) | 2024.04.15 |
10. Configuration (0) | 2024.04.15 |
9. Dependency Injection (DI) (0) | 2024.04.15 |