왜 '인증' 이라는 절차가 필요할까?
일반적으로 많이 사용하는 HTTP 프로토콜은 두 가지의 특징을 가진다.
1. 비연결성: 클라이언트가 요청을 보내고, 서버가 응답을 하면 연결을 끊어버린다.
2. 무상태성: 서버는 이전 요청이 누구로부터 왔는지 기억하지 못한다.
두 가지 특징 때문에 서버는 방금 로그인한 사용자가 어떠한 페이지를
요청했을때 누구인지 매번 다시 물어봐야 하고,
이러한 번거로움을 해결하고자 등장한 것이 세션과 토큰이다.
세션 기반 인증 (Session-based Authentication)
"서버가 사용자의 정보를 기억하고 있는 방식"
세션 방식은 누가 로그인했는지에 대한 명단을
서버 쪽(DB)에 직접 들고 있는 방식.
작동 원리
로그인: 사용자가 ID와 PW로 로그인 한다.
세션 생성: 서버는 정보를 확인하고, 서버 측 세션 저장소에
사용자 정보를 저장한 뒤 고유한 Session ID를 생성한다.
쿠키 전달: 서버는 응답 헤더의 Set_Cookie를 통해
브라우저에게 Session ID를 보낸다.
저장 및 재요청: 브라우저는 이 ID를 쿠키에 저장해두고,
요청 때마다 ID를 함께 보낸다.
검증: 서버는 쿠키 속의 Session ID를 보고,
"아 아까 로그인 했던 사용자구나!" 하고, 인지하게 된다.
장점 ✅
보안성: 실제 정보는 서버 측에 있으므로
클라이언트는 무의미한 ID 값만 가진다.
통제권: 서버가 특정 세션을 강제로 만료 시키는 것이 가능하다.
(예: 중복 로그인 방지, 계정 차단)
단점 ❌
서버 부하: 접속자가 많아지면 서버 메모리 사용량이 급증한다.
확장성 문제: 서버를 여러 대 운영(로드 밸런싱)할 경우,
A 서버에서 만든 세션이 B 서버에는 없기에
로그인이 풀리는 문제가 발생한다.
(해결하고자 Redis 같은 별도의 저장소가 필요합니다.)
토큰 기반 인증 (Token-based Authentication - JWT)
"사용자가 자신의 정보를 증명서 형태로 들고 다니는 방식"
최근 모바일 앱이나 MSA 환경에서 표준처럼 사용되는 방식이다.
주로 JWT (JSON Web Token)를 사용한다.
작동 원리
로그인: 사용자가 ID/PW를 보낸다.
토큰 생성: 서버는 정보를 확인하고,
비밀키를 이용해 암호화된 Token(JWT)을 생성한다.
(서버에 저장 X)
(비밀키는 환경 변수 등에 저장해 놓는다.)
전달: 생성된 토큰을 클라이언트에게 보낸다.
저장: 클라이언트는 토큰을 LocalStorage나 Cookie에 저장한다.
재요청: 요청 시 HTTP 헤더(Authorization: Bearer <token>)에
토큰을 담아 보낸다.
검증: 서버는 자신이 가진 비밀키로
토큰의 서명(Signature)만 확인하고 바로 승인한다.
장점 ✅
무상태성 (Stateless): 서버가 사용자 정보를 저장할 필요가 없어
서버 확장이 매우 자유롭다.
플랫폼 독립성: 웹뿐만 아니라 모바일 앱(iOS, Android)에서도
쿠키 이슈 없이 간편하게 사용 가능하다.
단점 ❌
수정 불가: 토큰 내의 정보가 바뀌어도 만료 전까지는 수정이 어렵다.
삭제 불가: 토큰을 탈취당해도 서버가 강제로 만료시킬 방법이 거의 없다. (이를 보완하기 위해 짧은 수명의 Access Token과
긴 수명의 Refresh Token을 함께 사용한다.)
보안 고려사항

세션 기반 인증의 보안: CSRF (Cross-Site Request Forgery)
위험: 사용자가 로그인된 상태에서 해커가 만든 가짜 링크를 클릭하면
브라우저가 자동으로 쿠키를 담아 요청을 보내버리는 특징을 이용한다.
(나는 클릭만 했는데, 내 계정으로 송금이 일어나는 방식)
대책 (SameSite): 쿠키 설정에 SameSite=Strict 또는 Lax를 적용한다.
이는 "우리 사이트에서 출발한 요청에만 쿠키를 붙여라"라고
브라우저에게 명령하는 것이다.

토큰 기반 인증의 보안: XSS (Cross-Site Scripting)
위험: 해커가 게시판 등에 악의적인 자바스크립트를 심어놓고,
사용자가 그 글을 읽을 때 그 사람의 브라우저에
저장된 토큰(LocalStorage 등)을 훔쳐가는 것이다.
대책 (HttpOnly & Secure)
HttpOnly: "이 쿠키는 임의의 자바스크립트로는 절대 못 읽어!
오직 HTTP 통신할 때만 서버로 보내줘."라고 설정하는 것이다.
해커의 스크립트가 실행되어도 쿠키를 읽을 수 없다.
Secure: "이 쿠키는 HTTPS(보안 연결)일 때만 전송해!"라고,
설정하여 통신 과정에서의 탈취를 막는다.
아래의 두 토큰을 조합하여 보안을 챙길 수 있다.
Access Token (단기권)
Refresh Token (재발급권)