- 서버가 각각의 요청을 독립적으로 처리하고 과거 요청에 대한 정보를 기억하지 않는다.
- 로그인과 같이 사용자의 상태를 유지해야 하는 기능을 구현하기 위해서 세션 기반 인증 방식과 토큰 기반 인증 방식을 사용한다.
세션: 클라이언트와 서버 간의 연결 상태
sessionID: 세션을 식별하기 위한 고유한 식별자
- 보통 쿠키를 통해 클라이언트에게 전달되고 클라이언트 측에서 저장
- 서버는 클라이언트가 요청을 보낼 때마다 해당 세션ID를 확인하여 사용자의 세션을 식별하고 유지
과정
- 로그인 요청: 클라이언트가 사용자 이름과 비밀번호 등을 포함한 정보를 서버에 POST 요청
- 로그인 성공 및 sessionID 생성: 서버는 클라이언트의 인증 정보를 확인하고, 로그인이 성공하면 세션을 생성하고 이에 대한 고유한 식별자인 sessionID를 부여
- 다음 요청 시 쿠키 자동 전송: 클라이언트는 저장된 sessionID를 쿠키로 갖고 있고, 이를 이용하여 다음 요청 시에 자동으로 요청 헤더에 쿠키로 설정하여 서버에 전송
- 서버에서의 sessionID 확인: 서버는 클라이언트로부터 받은 sessionID를 확인하여 해당 세션이 유효한지 확인 후, 유효한 sessionID일 경우 사용자의 로그인 상태를 유지하며 요청을 처리
session 데이터 저장
- DB저장
- 서버 재시작 후에도 데이터의 영속성이 보장된다.
- 여러 서버 간의 세션 공유가 용이하다.
- 세션 데이터를 DB에 저장하려면 데이터를 직렬화하고 역직렬화해야 하는 과정이 필요하다.
- 서버저장
- 직렬화 및 역직렬화 과정이 없어 더 빠른 응답 속도를 제공할 수 있다.
- 모리 접근이 디스크 I/O보다 빠르기 때문에 높은 성능을 제공할 수 있다.
- 서버 메모리 사용량이 증가할 수 있다.
사용자의 상태 정보를 토큰에 저장하여 서버에 유지
토큰을 처리하는 서버와 나머지 컨텐츠를 처리하는 서버 간의 역할을 구분
- 토큰 처리와 인증을 담당하는 서버를 분리함으로써, 서로 독립적인 환경을 유지
- 컨텐츠를 처리하는 서버들을 stateless하게 유지
과정
- 로그인 요청
- 토큰 발급: 로그인이 성공하면, 인증 서버에서는 해당 사용자를 위한 토큰을 생성하고 이를 클라이언트에게 전달
- 인증이 필요한 요청: 클라이언트가 원하는 콘텐츠나 서비스에 접근할 때, HTTP 요청의 Header에 Authorization 또는 Cookie 등을 사용하여 토큰을 담아 서버에 요청
- 토큰 검증 및 인증: 서버는 요청에 포함된 토큰을 검증하고, 토큰이 유효하고 유효기간 내에 있다면 해당 요청을 처리
- 토큰이 유효하지 않거나 만료되었다면, 인증 오류를 반환하거나 요청을 거부
- 저장 위치
- Token: 클라이언트 측 localStorage, sessionStorage, 쿠키 등에 저장
- Session: 서버 측서버 메모리, 데이터베이스, 파일 시스템 등의 영구적인 저장소에 저장
- 요청
- Token: 클라이언트가 서버에 요청 시에 토큰을 함께 전송하여 인증 요청
- Session: 클라이언트가 서버에 요청 시에 세션 ID를 함께 전송하여 서버에서 세션을 찾고 인증 처리
- 확장성
- Token: 서버의 상태를 유지하지 않으므로, 여러 서버 간에도 사용자의 인증을 공유할 수 있다.
- Session:세션을 서버 측에 저장하기 때문에, 동일한 세션을 여러 서버 간에 공유하기가 어려울 수 있다.
인증과 권한 부여를 위한 토큰 기반의 표준으로 헤더, 페이로드, 서명 세 부분으로 구성된다.
Json 객체로 인코딩되어 메세지 인증 및 암호화에 사용된다.
구조
- Header: 토큰의 유형과 해싱 알고리즘
- Payload: 토큰의 실제 정보가 담기는 부분으로, 키-값 쌍들을 포함
→ 유저 데이터(이메일, 토큰 유효기간, 토큰 발급자 등)- Signature: 헤더와 페이로드를 합친 후, 이를 비밀 키로 서명하여 생성
→ SIGNATURE = 헤더와 페이로드를 Base64로 인코딩한 값 + 비밀키 + 헤더에 명시된 서명알고리즘
→ 토큰이 변조되지 않았음을 증명하고, 토큰이 유효한지 검증하는 데 사용
JWT 장점
- 토큰에 사용자 인증 정보가 포함되어 있어 별도의 인증 저장소가 필요하지 않다.
- 다른 토큰과 비교했을 때, JWT는 정보를 JSON 기반으로 가지고 있어서 경량화되어 있다.
- JSON 기반으로 인코딩 및 디코딩을 수행하기 때문에 직렬화와 역직렬화가 간편하다.
Access Token: 인증을 위한 주요한 토큰
- 만료 기간을 짧게 설정하여 보안을 강화
- Access Token이 짧게 설정되어 있기 때문에 탈취될 경우, 유효 시간이 짧아 정보 유출 위험이 낮습니다. 하지만 만료가 자주 발생하므로 Refresh Token을 사용하여 새로운 Access Token을 발급한다.
Refresh Token: Access Token의 만료되었을 때 새로운 Access Token을 발급하는 데 사용되는 토큰
- 주로 클라이언트가 서버에게 Access Token을 요청하면 함께 발급되며, Access Token이 만료되면 Refresh Token을 사용하여 새로운 Access Token을 받아오게 된다.
- 만료 기한을 길게 설정하여, Access Token의 만료마다 사용자에게 로그인을 다시 요구하지 않고 새로운 Access Token을 발급함으로써 인증에 대한 비용을 줄일 수 있다.
Access Token & Refresh Token 발급 과정
- 서버에 로그인 요청
- 인증 및 인가: 서버에서 사용자 인증을 통해 로그인이 성공하면, Access Token 및 Refresh Token을 발급
- 토큰 수신: 클라이언트는 서버로부터 Access Token과 Refresh Token을 수신
- 토큰 사용: 클라이언트는 서버의 보호된 자원에 접근할 때마다 HTTP 요청의 Header에 Access Token을 포함하여 요청
- Access Token이 만료되면, 클라이언트는 Refresh Token을 사용하여 새로운 Access Token을 발급받는다.
토큰 사용시에 주의할 점
- Bearer 접두사를 통해 클라이언트가 서버에게 토큰을 전달하고 있는지 명시
- HTTPS 사용: 통신을 보호하기 위해 HTTPS를 사용
- 유효 기간 짧게 설정: 토큰의 유효 기간을 짧게 설정하여 보안을 강화하고 토큰의 노출 시간을 최소화
- URL에 토큰 전달 금지
- 쿠키의 SameSite 설정: 토큰을 쿠키에 저장하는 경우, SameSite 속성을 Strict로 설정하여 쿠키가 설정된 도메인과 동일한 출처에 있는 경우에만 해당 쿠키가 전송 되도록 한다.
- 다른 도메인에서 쿠키가 전송되는 것을 방지하여 공격자가 사용자의 정보를 탈취하거나 조작하는 것을 어렵게 만든다.
모리접근 좋죠