티스토리 뷰
로그인은 됐는데, 왜 또 로그인하라는 걸까?
백엔드 API를 처음 설계했을 때
로그인 기능 자체는 비교적 쉽게 구현했습니다.
문제는 그 다음이었습니다.
- 새로고침하면 로그인이 풀리고
- 서버를 여러 대로 늘리자 인증 오류가 발생
인증이라는게 이렇게까지 어려운 문제였나 . . .?
이 고민의 끝에서 JWT (Json Web Token) 를 제대로 이해하지 않으면 안 되겠구나 느꼈습니다.
이 글은 JWT 를
- 왜 쓰게 되었는지
- 어떤 문제를 해결했는 지
- 막연히 쓰다 겪은 시행착오
중심으로 정리한 문제 해결 기록입니다.
문제 상황 - 세션 기반 인증의 한계에 부딪히다
처음 사용했던 방식 : 세션 (Session)
초기 구조는 전형적인 세션 기반 인증이었습니다.
1. 로그인 성공
2. 서버에 세션 저장
3. 클라이언트는 세션 ID를 쿠키로 보관
4. 이후 요청마다 세션 확인
그런데 실무에서 문제가 터졌습니다.
- 서버를 2대 이상으로 늘리는 순간 -> 특정 서버에서는 로그인 상태가 풀림
- 외부 API 연동 -> 쿠키 기반 인증이 애매해짐
로그인 상태를 서버가 계속 기억해야 한다는 점이 확장성과 운영 측면에서 계속 발목을 잡았습니다.
원인 분석 - 인증 상태를 누가 들고 있어야 하는가
" 사용자가 로그인했다는 사실을 누가 기억해야 할까? "
세션 방식 -> 서버
JWT 방식 -> 클라이언트
이 차이가 모든 구조를 갈랐습니다.
그럼 JWT가 무엇인가 - 서버의 기억을 토큰으로 옮긴 방식
JWT (Json Web Token)는 인증 정보를 하나의 토큰으로 만들어 클라이언트에게 맡기는 방식입니다.
JWT 구조
점(.)으로 구분된 세 부분으로 구성
Header.Payload.Signature
Header
- 토큰 타입 (JWT)
- 서명 알고리즘 (HS256 등)
{
"alg": "HS256",
"typ": "JWT"
}
Payload
- 사용자정보 (claims)
- 만료 시간, 권한 등
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"iat": 1516239022
}
Signature
- Header + Payload + Secret Key
- 위조 여부 검증용
해결 과정 - JWT 기반 인증 흐름으로 재설계
로그인 시
- 아이디 / 비밀번호 검증
- JWT 생성
- 클라이언트에 전달
이후 요청 시
클라이언트: Authorization 헤더에 JWT 포함
서버:
- 토큰 추출
- 서명 검증
- Payload에서 사용자 정보 사용
결과
| 항목 | 세션 | jwt |
| 서버 상태 | 상태 저장 필요 | 무상태(stateless) |
| 서버 확장 | 까다로움 | 매우 쉬움 |
| 모바일/외부 연동 | 불편 | 용이 |
| 인증 로직 | 복잡 | 단순 |
JWT를 쓰며 겪은 풀어야 할 문제
1. 로그아웃이 어렵다
JWT는 서버에 저장되지 않기 때문에 즉시 무효화가 어렵다
-> 해별방식
- Access Tocken + Refresh Token
- 블랙 리스트 관리 ( 이러면 jwt를 쓰는 장점이 없어지지 않나 .. . .? )
2. 만료 시간 설계가 중요하다
- 너무 길면 보안 위험
- 너무 짧으면 사용자 경험 저하
3. 탈취되면 끝
-> refresh token rotation
무조건 JWT가 좋은건 아닌 것 같습니다
단일서버
내부 관리자 페이지
복잡한 권한 관리 필요없는 경우에는
세션이 더 단순하고 안전합니다.
JWT는 편리한 인증 도구이지 보안 문제를 대신 해결해 주는 기술은 아닙니다.
세션을 대체하는 게 아니라 상황에 맞는 선택지일 뿐이라고 생각합니다.
이후로는 인증 방식을 정할 때
우리 서비스는 상태를 어디까지 서버가 책임져야 하는가를 먼저 고민하게 되었습니다.
다음 포스팅은
- Total
- Today
- Yesterday
- 코랩 워드클라우드
- 인스턴스 생명주기
- AI
- 이벤트유효성
- dl
- transformer
- 데이터옵션
- 자연어처리
- 사용자정의이벤트
- Await
- 콜백callback
- KoELECTRA
- 코랩 워드클라우드 한글깨짐
- gradientclipping
- 컴포넌트간데이터전달
- 인스턴스 구조
- 인스턴스 옵션
- 코랩 한글깨짐
- 로짓함수
- 사전학습모델
- 프론트엔드
- 이벤트에미터
- PROMISE
- async
- defaultparameter
- 리액트
- NLP
- 컴포넌트간통신
- ML
- 리액트 폴더구조
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |