[TIL] 로그인에 관한 세션 그리고 JWT 토큰 방식

DEVELOPERS_Ivan ㅣ 2023. 11. 18. 16:59

목차
1_오늘의 TIL
2_로그인(Login)
3_쿠키(Cookie)
4_세션(Session)
5_제이슨 웹 토큰(JWT)
5-1_JWT(Json Web Toke) 구성
6_쿠키, 세션, JWT 차이점
7_마무리

1_오늘의 TIL

부트 캠프를 통해 팀 프로젝트 기간이 시작되었다,
팀 프로젝트의 주제는 가구 쇼핑몰이 선정되었고
공지사항, QNA, 로그인/회원가입, 결제, 쿠폰발급까지 나와 팀원 1명이 담당하게 되었다.
금요일 학원 수업이 끝난 후 개발자 친구의 집으로 향하여 개인 토이 프로젝트(블로그 포트폴리오 만들기) 에
로그인 코드를 붙여보는 연습을 하려고 하였다.
여기서 오늘의 블로그 주제!가 발생되었다.
개발자 친구가 JWT와 세션의 차이점을 물어봤는데
...
대답을 하지 못하였다.
문제의 심각성을 알게 되었고 개념부터 잡고 가기 위해 블로그에 학습한 부분을 기록해보려고 한다.

그래서 오늘의 주제는 로그인에 관한 주제로 JWT와 세션의 방식과 차이점을 기록해 본다.
 

2_로그인(Login)

출처 : opennaru

1) 인증( Authentication )

- 목적 : 사용자가 시스템에 로그인할 때, 그 사용자가 자기 자신이라고 주장하는 신원을 확인하는 것입니다.
- 프로세스 : 주로 아이디와 패스워드, 혹은 다양한 인증 수단을 사용하여 사용자가 누구인지 확인합니다.
- 결과 : 인증이 성공하면 시스템은 해당 사용자를 신뢰하고, 해당 사용자의 계정에 접근할 수 있는 권한을 부여합니다.


2) 인가( Authorization )

- 목적 : 로그인한 사용자에 대한 권한을 관리하여, 해당 사용자가 특정 리소스나 기능에 접근할 수 있는지를 결정하는 것입니다.
- 프로세스 : 사용자의 권한, 역할, 그룹 등을 기반으로 특정 화면이나 리소스에 대한 접근을 허용하거나 거부합니다.
- 결과 : 인가는 사용자의 권한이나 역할에 따라 동적으로 결정되어, 로그인한 사용자가 어떤 작업을 수행할 수 있는지를 제어합니다.


3) 요약 및 보안상의 고려사항

위 내용을 정리하자면 로그인은 인증(사용자 확인), 인가(권한 관리)의 조합으로 구성되어 있습니다.

인증은 사용자가 누구인지 확인하고,

인가는 해당 사용자가 어떤 권한과 역할을 가지고 있는지를 결정하여 특정 리소스에 대한 접근을 제어합니다.
사용자의 신원확인을 하고 그에 따른 권한을 부여하여 시스템 보안을 유지합니다.
 
이후 웹 사이트로 예로 들면
방문자 중에는 로그인 회원과 비로그인 회원이 있을 것이고  그에 따라 로그인을 통해서만 가능한 기능들을
(예시 : 댓글달기 등..) 허용을 해줄지 말지를 매번 요청하고 결정해서 응답해야 합니다.
 
로그인을 하기 위해서는 데이터베이스에 저장된 사용자 계정의 해시값 등을 꺼내온 다음에 사용자의 암호를 복잡한 알고리즘으로 계산한 값 일치하는 과정 등을 거치게 되며 서버에 전달하게 하고 그 이후 웹 사이트에 기능들을 사용할 수 있게 됩니다. 하지만 여기서 매번 신원확인을 위한 데이터(아이디와 패스워드) 같은 정보를 요청하고 응답하는 과정에서 보안상의 위험이 생기게 됩니다.

 

3_쿠키(Cookie)

- 목적 : 사용자의 브라우저에 정보를 저장하여 상태를 유지하고, 클라이언트와 서버 간에 데이터를 주고받습니다.
- 프로세스 : 서버에서 생성한 쿠키를 응답 헤더에 실어 클라이언트에게 전송하고, 이후 클라이언트는 해당 쿠키를 요청 헤더에 포함시켜 서버로 전송합니다.
- 결과 : 클라이언트에 저장되는 쿠키를 통해 사용자의 상태를 추적하고 유지하며, 서버는 클라이언트의 상태를 파악하여 맞춤형 서비스를 제공합니다.
 

4_세션(Session)

- 목적 : 사용자의 상태를 서버에 저장하여 클라이언트와 서버 간에 지속적인 상태 유지를 가능케 합니다.
- 프로세스 : 클라이언트가 서버에 최초로 접속하면 서버는 사용자에 대한 세션을 생성하고 세션 ID를 클라이언트에게 부여합니다.
이후 클라이언트는 세션 ID를 이용하여 서버에 상태를 저장하거나 조회합니다.
- 결과 : 서버에 저장된 세션을 통해 사용자의 상태를 지속적으로 유지하고, 클라이언트와 서버 간의 상호작용을 통해 동적인 서비스를 제공합니다.
세션은 클라이언트-서버 간의 양방향 통신이며, 서버가 세션을 관리합니다.
세션은 서버에서 사용자 상태를 유지하는데 중점을 두게되는데 이 방식을 스테이트풀(Stateful) 라고 합니다.
 

5_제이슨 웹 토큰(JWT)

- 목적 : 정보를 안전하게 전송하고 인증에 사용되며, 클라이언트와 서버 간에 정보를 주고받습니다.
- 프로세스 : 클라이언트가 서버에 로그인 요청을 보내면 서버는 유저 정보와 함께 JWT를 생성하여 클라이언트에 전달합니다.
클라이언트는 받은 JWT를 안전한 곳에 저장합니다.(일반적으로 브라우저의 localStorage 또는 쿠키에 저장)
- 결과 : 클라이언트는 JWT를 저장하고 필요할 때마다 요청에 포함시켜 서버에 인증 정보를 전달하며, 서버는 JWT를 통해 클라이언트의 신원을 검증하고 보안적으로 효과적으로 정보를 전달합니다.
토큰의 내용은 클라이언트에서 디코딩할 수 있지만, 서명은 서버에서만 확인할 수 있습니다.
JWT는 클라이언트에서 서버로의 단방향 전송이 주요 사용 방식입니다.
JWT는 클라이언트 측에서 상태를 유지하지 않고, 필요한 정보를 토큰에 담아서 사용합니다 이 방식을 스테이리스(Stateless) 라고 합니다.
 

5-1_JWT(Json Web Toke) 구성과 구조

JWT(Json Web Token)는 JSON 객체 형태로 구성되어 있으며 기본적으로 3가지의 구조로 나뉩니다.

1) 헤더( Header ) : 

JWT의 헤더는 두 가지를 기술합니다.
토큰 타입( Type ) : 토큰의 타입을 지정합니다. 일반적으로 고정값 "JWT"로 설정됩니다.
알고리즘( Algorithm) : 3)서명 값을 만드는데 사용될 해싱 알고리즘이 지정됩니다. (암호화 방식 예 : HMAC SHA 256 또는 RSA 등..)

{
  "typ": "JWT" // 토큰 타입
  "alg": "HS256", // 알고리즘
  
}

 
2) 페이로드( Payload ) :

페이로드는 실제로 전송하려는 클레임( claim ) 정보를 포함합니다. 클레임은 조각 단위를 의미함.
- 등록된 클레임( Registered Claims) :  토큰에 대한 정보를 제공하기 위해 미리 정의된 클레임입니다.
- 공개 클레임( Public Claims ) :  사용자 정의 클레임으로, 충돌을 방지하기 위해 URL 형식으로 지정됩니다.

- 비공개 클레임( Private Claims ) :  토큰을 생성한 서비스와 클라이언트 간에 사용되는 사용자 정의 클레임으로, 서비스와 클라이언트 간의 협의에 따라 정의됩니다.

{
  "sub": "1234567890",	// 토큰의 서비스를 식별
  "name": "John Doe", 	// 토큰에 포함된 사용자의 이름
  "admin": true		// 사용자가 관리자 권한을 가지고 있는지 여부를 나타냄, Boolean 값을 가짐
}

 
3) 서명 ( Signature ) :

서명은 헤더의 인코딩, 페이로드의 인코딩, 비밀 키를 사용하여 생성됩니다.
서명을 통해 토큰이 신뢰할 수 있는지 확인할 수 있습니다.

HMACSHA256(
  base64UrlEncode(header)  + "." +
  base64UrlEncode(payload),
  secret
)

 
base64UrlEncode(header):

헤더를 URL 안전한 base64 인코딩으로 변환합니다.
base64UrlEncode(payload):

페이로드를 URL 안전한 base64 인코딩으로 변환합니다.
base64UrlEncode(header) + "." + base64UrlEncode(payload):

앞서 변환한 헤더와 페이로드를 점(.)으로 연결합니다.
HMACSHA256(..., secret):

연결된 문자열과 비밀 키(secret)를 사용하여 HMAC-SHA256 해시를 생성합니다.
 

[base64UrlEncode(header)].[base64UrlEncode(payload)].[signature]

Json 형태인 각 부분은 Base64로 인코딩 되어 표현됩니다. 각 부분을 이어 주기 위해 .구분자를 반환합니다.
 

6_쿠키, 세션, JWT 차이점

1) 저장 위치 :

- 쿠키 : 클라이언트 브라우저에 저장됩니다.
- 세션 : 서버에 저장됩니다.
- JWT : 클라이언트에 저장됩니다.

2) 보안성 :
쿠키 > 세션 > JWT
- 쿠키 : 클라이언트에서 수정 가능하므로 보안에 취약할 수 있습니다.
- 세션 : 서버에 저장되어 클라이언트에서 직접 수정할 수 없어 상대적으로 안전합니다.
- JWT : 서명을 통해 안전하게 정보를 전송하므로 보안성이 높습니다.

3) 유지 기간 : 
쿠키 > 세션 > JWT
- 쿠키 : 미리 설정된 만료일까지 유지됩니다.
- 세션 : 클라이언트가 로그아웃하거나 브라우저를 닫을 때까지 유지됩니다.
- JWT : 토큰에 설정된 만료일까지 유지됩니다.

4) 서버 부하 :
쿠키 > JWT > 세션
- 쿠키 : 클라이언트의 요청마다 서버에 전송되므로 부하가 적습니다.
- 세션 : 서버에 저장되고 관리되기 때문에 서버 부하가 있을 수 있습니다.
- JWT : 클라이언트에 저장되므로 서버 부하가 적습니다.



7_마무리

웹 개발에서 로그인에 관해서 쉽게 생각하면 안 되는 부분임을 알게 되었다..
민감한 정보가 담겨 있기 때문에 보안 이슈의 문제로 특징에 맞게 어떤 방식을 채택할 것인지 인지를 하고 구성을 해야 될 거 같다.
로그인 기능을 진행해 보면서 블로그에 추가적인 부분을 추가 및 수정 보완해야겠다.

 

'Java' 카테고리의 다른 글

[Java] 객체 지향 프로그래밍(OOP) 장, 단점 & SOLID 5가지의 원칙  (1) 2024.03.14
[TIL] 접근 제어 지시자와 정보 은닉  (0) 2023.12.11
[Java] chapter_15  (0) 2023.09.27
[Java] chapter_14  (0) 2023.09.27
[Java] chapter_12  (0) 2023.09.26