# 인증
인증이란 누군가 또는 시스템이 실제로 누구인지 혹은 어떤 시스템인지 결정하는 과정이다. 사용자의 자격 증명 정보와 서버의 자격 증명 정보와 일치하는지 확인하고 이 절차를 통과한 것들에 대해 엑세스 제어를 제공한다.
쉽게는, 돈을 인출하려고 은행에 가면 은행원에게 통장과 도장 혹은 사인을 제시해야한다. 내가 제시한 정보가 은행의 정보와 맞지 않는다면 돈을 인출할 수 없게 된다.
## 인증의 유형
1. SFA(단일요소인증) : 자격 증명 정보로써 사용자 ID와 암호만을 요구한다. SFA는 ID와 비밀번호만 알아도 보안에 쉽게 문제가 생길 수 있다는 단점이 있다.
2. 2FA : 자격 증명 정보를 한가지 더 요구한다. 지문이나 디바이스의 고유코드를 추가적으로 요구해 인증을 강화했다.
3. MFA : 자격 증명 정보를 3개 이상 요구한다. 추가적으로 사용자가 직접 답변해야하는 질문을 자격증명 정보에 추가하여 보안을 강화한 인증유형
# 인가
인가는 사용자에게 특정 리소스 또는 기능에 대한 액세스 권한을 부여하는 프로세스이다. 누군가에게 서버가 가지고 있는 파일을 다운로드 할 수 있는 권한을 부여하거나, 애플리케이션에 대한 관리 엑세스 권한을 제공하는 것 등이 인가의 예이다.
인가 절차는 항상 먼저 인증 절차를 먼저 거쳐야 한다. 특정 권한을 부여하기 전에 사용자의 자격증명을 먼저 확인해야한다.
# Session or Token 기반 Authentication
웹은 데이터를 교환하기 위해 HTTP 방식을 사용하는데, HTTP는 Stateless한 특성을 가지고 있다. 각 HTTP 통신은 과거의 통신에 대한 정보를 전혀 알지 못하기 때문에 매 통신마다 필요한 정보를 담아서 요청을 해야한다.
따라서, 로그인 후 상품 구매를 하려고 할 때, 상품 구매에 대한 요청을 보낼 시 로그인을 위한 인증정보를 계쏙 요청에 담아서 보내야 한다는 뜻이다.
이런 불편함을 없애고자 일부 정보는 Stateless가 아닌 Stateful한 상태를 유지해야하며, 이를 위해서 Session과 Cookie 또는 Token 방식의 인가를 진행할 수 있다.
## Session 기반
Session과 Cookie를 이용한 Authentication에 대해 알아보기 전에 Session과 Cookie의 차이에 대해 알아야한다.
### Session
같은 사용자가 브라우저를 통해 웹 서버에 접속한 시점부터 브라우저를 종료하여 연결을 끝내는 시점 동안에 들어오는 Request를 하나의 상태로 보고, 그 상태를 유지하게해서 사용자와 웹 서버가 연결된 상태
서버가 Session에 대한 정보를 저장하고, 클라이언트에게는 Session을 구분할 수 있는 ID를 부여하게 되는데 이것을 Session ID라고 한다.
클라이언트에서 Request를 보낼 때, Session ID를 함께 보내서 클라이언트의 상태를 확인할 수 있다.
### Cookie
Cookie는 클라이언트의 컴퓨터에 저장되는 데이터 파일이다. 이름, 값, 만료 날짜/시간, 경로 정보 등으로 구성된다. Cookie는 하나의 도메인 당 20개를 가질 수 있으며, 1개 당 4Kbyte를 넘길 수 없다.
서버에서는 클라이언트의 Request에 대한 Response의 Header에 Set-Cookie 속성을 부여해서 클라이언트에게 Cookie를 제공할 수 있다.
예를 들어 장바구니 기능은 과거에는 로그인을 해야지만 사용할 수 있었는데,(DB에 저장하기 때문에) 최근에는 Cookie를 이용해서 로그인을 하지 않은 상태로도 장바구니에 담은 상품을 알 수 있다.
## Session과 Cookie를 이용한 인증 Flow
1. 사용자가 로그인을 하기 위해 인증 정보를 가지고 인증을 요청
2. 인증이 완료되면 사용자의 Session 정보를 서버의 메모리에 저장 후 생성되는 Session ID를 Set-Cookie를 통해 전달
3. Session ID가 포함된 Cookie는 브라우저에 저장되고, Request를 서버에 보낼 때 함께 보내진다.
4. 서버는 사용자가 보낸 Session ID와 서버 메모리에 저장된 Session ID를 비교해서 Verification을 수행 후 권한을 인가한다.
## Session 기반 인증의 장단점
### 장점
1. Session ID 자체에는 개인정보를 담고 있지 않기 때문에 보안성이 높다.
2. 서버에서 정보를 관리하기 때문에 데이터 손상 우려의 가능성이 적다.
3. 서버에서 상태를 유지하기 때문에, 로그인 여부 확인이 쉽고 경우에 따라서는 강제 로그아웃 등의 제재를 가할 수 있다.
### 단점
1. 서버에서 모든 사용자의 상태를 관리해야 하기 때문에 사용자의 수가 증가할수록 서버에 부하가 증가한다.
2. 사용자가 증가해서 서버를 Scale Out해야할 때 Session의 관리가 어렵다.
3. 디바이스끼리 공동으로 사용할 때 중복 로그인 처리가 되지 않는 등의 신경써야할 부분들이 증가한다.
# Token 기반
## Token
Token은 사전적 의미로는 금액을 지불해야 하는 서비스를 사용할 때 필요한 동전이라고 생각하면 쉽게 이해할 수 있다. 웹에서의 Token도 마찬가지로 Token을 가지고 있으면 해당 서비스를 이용할 수 있는 권리가 생긴다고 생각하면 쉽다.
더 자세하게 말하면 Token은 제한된 리소스에 대해 일정 기간 동안 접근 할 수 있는 권한을 캡슐화 한 것이다. 일반적으로 의미를 알 수 없는 임의의 문자열 형태로 발급한다. 또한, 접근할 수 있는 범위와 접근이 가능한 기간을 통제할 수 있다.
## Token 기반의 인증 Flow
1. 로그인을 위한 인증 정보를 가지고 인증 절차를 요청
2. 인증이 완료되면 사용자 식별 정보를 가지고 있는 Token을 발급하여 Response의 Body에 담아 클라이언트에게 전달
3. 클라이언트는 Token을 local storage에 저장하고 Request 할 때마다 저장된 Token을 Header에 담는다.
4. 서버는 클라이언트에서 받은 Token 정보를 Verification 한 뒤, 해당 유저에게 권한을 인가.
## Token 기반 인증의 특징
### 장점
1. Token을 클라이언트에서 저장하므로 서버의 메모리나 DB에 부담이 없음.
2. 상태 정보를 서버에서 관리하지 않기 때문에 서버의 Scale Out에 용이하다.
3. 다양한 디바이스에서의 멀티 환경에서 사용이 용이하다.
4. Token 만료 시간을 짧게 설정하면 안정성을 높일 수 있다.
### 단점
1. 서버에서 사용자의 상태를 저장하고 있지 않기 때문에 사용자의 로그인 여부 확인이나 강제 로그아웃 등의 제재를 가하기 어렵다.
2. 임의로 토큰을 수정하거나 구조 변경이 생기면 서버에서 확인할 수 없다.
3. Payload 부분에 식별을 위한 정보들이 포함되어 있어 Session ID의 길이보다 길어져 전송 데이터의 크기가 증가한다.
4. XSS(Cross-stie Scripting) 공격에 취약해서 Payload에 민감한 정보를 포함할 경우 위험할 수 있다.
# Token 기반 인증의 이점
## Stateless
사용자 측에서 정보를 관리하기 때문에 서버의 상태를 Stateless하게 유지할 수 있다. 이는 곧, 사용자로부터 받은 Request만을 가지고 작업을 수행할 수 있다는 뜻이 된다.
## Scalability
A서버와 B서버가 있고, Session 기반의 인증을 한다고 가정했을 때 처음 A서버에서 Session ID를 발급받고 A서버가 그 Session ID를 가지고 있을 때, A서버의 사용자가 많아 B서버로 요청을 보냈을 때, B서버는 해당 사용자의 Session ID를 가지고 있지 않기 때문에 인증이 어려워진다. 하지만 Token 기반 인증은 그런 관계성이 없기 때문에 서버의 확장성 부분에서는 이점을 가지고 있다.
## Security
Cookie를 전달하지 않기 때문에, CSRF(Cross Site Reqeust Forgery) 공격을 방지하는데 도움이 된다.
'Back-end' 카테고리의 다른 글
[Nest] Nest + TypeORM 환경에서 DTO 데코레이터, Exception, Exception Filter 커스텀 해보기 (feat. 에러 메시지) (0) | 2024.06.10 |
---|