본문 바로가기

Coding/내일배움캠프

[내일배움캠프] 인증 메커니즘의 역사와 개념, 내가 만든 쿠키, Stateful vs Stateless - Node.js 4기 TIL | Day 41 | 24.02.12.(월)

`인증`

- 인증(Authentication) : 사용자가 누구인지 확인하는 과정

`비밀번호 기반 인증`

- 가장 기본적인 인증 방법이지만, 후술할 인증 방법을 적용하기에 앞서서 항상 꼭 필요한 인증방법

`내가 만든 쿠키~🍪는 왜 나왔을까?`

- 매번 아이디와 비밀번호를 검증하는 것은 비효율적이고 번거로운 일이다.
- 그래서, 인터파크 티켓 앱 + 모바일 티켓의 조합으로 검증
    - 1) 쿠키 ➡️ 인터파크 티켓앱
    - 2) 세션 ID 혹은 JWT ➡️ 입장 모바일 티켓
- 즉, 쿠키는 다음에 나올 “세션 ID”나 “JWT”와 같은 “인증 토큰”을 전달하는 매개채로 생각하시면 된다.
- 쿠키 === 셔틀

`세션 (stateful)`

- 세션
: 서버에서 직접 사용자 정보를 관리하는 메커니즘
- 서버는 세션 관련 정보를 보통은 메모리에 들고 있다. 왜냐하면, 휘발되면 유저가 재로그인하면 그만이고, 세션 ID 기반으로 유저의 정보를 조회하는 행위를 DB 기반으로 하게되면 이 역시 DB에 부담이 될 수 있거든.
- 쿠키를 태워서 보내는 세션 ID 값이 남들에게 노출되면 해킹당할 수 있다.
- JWT도 마찬가지이다. Access Token이나 Refresh Token이 탈취되었을 때 계정이 해킹을 당할 수 있게 된다.
- 🍯 꿀팁 : 쿠키에 httpOnly와 secure 옵션을 넣어주시면 상당히 안전하게 전송할 수 있어요!

- httpOnly 옵션
    - 해당 옵션을 true로 하면, JavaScript를 통한 쿠키의 접근을 차단할 수 있음
    - 즉, XSS(Cross-Site Scripting) 공격을 통해서 세션 ID나 JWT를 탈취하는 것을 방지할 수 있다.
- secure 옵션
    - 쿠키를 HTTPS를 통해서만 전송하게 해준다.
    - HTTPS를 적용해서 배포하는 경우 세팅해주시면 좋다.
- sameSite 옵션
    - CSRF(Cross-Site Request Forgery) 공격을 막기 위해서 필요한 옵션!

`Stateful과 Stateless 간략 소개`

- Stateful
    - 과거 정보를 기억하고 현재 상태에 영향을 미칩니다.
    - 예시 : 데이터베이스, 웹 서버 세션, 챗봇 대화 상황
- Stateless
    - 과거 정보를 기억하지 않고 항상 같은 입력에 같은 출력을 제공합니다.
    - 예시 : 웹 API, 함수, 캐싱

특징 Stateful Stateless
상태 유지 과거 정보 기억 과거 정보 기억하지 않음
상태 변화 입력/시간에 따라 변화 입력에 관계없이 변화 없음
복잡성 복잡하고 이해하기 어려움 단순하고 이해하기 쉬움
디버깅 디버깅 어려움 디버깅 용이
확장성 확장 어려움 확장 용이



- 적용 분야
    - Stateful : 데이터베이스, 웹 서버, 챗봇, 게임, 머신 러닝 모델
    - Stateless : 웹 API, 함수, 캐싱, 컨테이너, 마이크로서비스, 분산 시스템

- 결론
    - 상황에 따라 적절하게 선택해야 합니다.
    - 과거 정보가 중요하고 상호 작용/동적 행동 모델링 필요 ➡️ Stateful
    - 단순하고 확장 가능한 시스템 필요 ➡️ Stateless

- 세션 - Stateful
- JWT - Stateless

`JWT (stateless)`

- JWT는 stateless하다.
- 서버가 세션 Map과 같이 클라이언트의 상태를 보존하지 않아도 상관없다는 의미

- JWT 설계 철학
    - 유저를 인증하는 데 필요한 정보는 토큰에 위임시키고 단지 검증만 하면 필요한 정보를 얻을 수 있게 된다.
    - 이렇게 되면 메모리에서 해당 유저의 정보를 조회하는 연산을 하지 않아도 된다.

- JWT 기법이 적용된 후, 서버가 하는 일은 매우 단순해졌다.
    1. JWT 토큰 (엑세스 토큰, 리프레시 토큰) 발급
    2. 내가 발급한 JWT 토큰인지 확인

    - 1번의 경우 모든 서버가 동일한 key를 매개로 발급을 한다는 전제가 지켜지면 된다.
    - “디지털 서명” : JWT가 서버에서 생성되었음을 검증하고, 토큰의 내용이 중간에 변경되지 않았음을 보장
    - 따라서, 클라이언트의 상태의 보존 없이 동일한 key만 있으면 어느 서버에서든 인증 처리를 할 수 있게 되었다. 이렇게 되면 서버를 무한대로 확장해도 걱정이 없다.

- 엑세스 토큰과 리프레시 토큰 .. 왜 2개로 분리했냐?
    - 엑세스 토큰과 리프레시 토큰은 생성 시 유효기간을 입력하여 발급하는 구조
    - 엑세스 토큰은 리프레시 토큰에 비해서 훨씬 짧은 유효기간으로 세팅됨 (보통 15분 ~ 길어야 몇 시간)
    - 토큰이 노출되었을 때 피해 시간을 최소한으로 가져가기 위함

1. 긴 유효기간으로 세팅된 레프레시 토큰으로 API를 사용하지 않게 함으로써 최대한 정체를 드러내지 않게하고
2. 다소 짧은 유효기간으로 세팅된 엑세스 토큰으로 대부분의 인가가 필요한 API들을 호출

💡 엑세스 토큰은 짧은 유효 기간으로 보안을 유지하고, 리프레시 토큰은 사용자 경험을 개선한다.


- 항상 HTTPS 위에서 통신하게 하고 쿠키에 httpOnly, secure 옵션 설정만 잘해도 충분히 보안이 확보된다! 디테일 잊지 말자!