세션 VS JWT 세션을 택하게 된 이유

2023. 4. 25. 15:22카테고리 없음

 

프로젝트 진행 고려 사항 


User 기능  ( 로그인, 회원가입, 리뷰작성, 회원탈퇴, opt인증) 과 같은 기능 구현 담당했다.

 

로그인 기능구현 중  사용자가 로그인 했을때 이 로그인 세션 정보를 어떻게 계속 유지하여

인증을 받은 사용자만이  카페 주문 예약, 리뷰 작성 과 같은 기능을 사용 할수 있을지 

고민하다 로그인 상태를 유지하기 위한 방법으로 세션 ,JWT 를 찾아보게 되었다.

 

 

 

세션을 이용한  상태 유지 


세션 ?

세션을 이용한 방법은 사용자가 로그인시 서버는 식별자인 sessionid를 생성한 후 server에 저장 한 다음 사용자에게 응답 결과로 sessionid를 보내준다 . 그러면 사용자는 그 세션아이디를 저장하고 요청을 보낼때마다 세션 id를 같이 보내며  로그인 상태를 유지 할수 있다.

 

세션 방식의 장점 

 

서버가 세션 아이디를 바탕으로 사용자를 식별하고 사용자의 데이터를 서버에 저장 관리 한다. 그렇기에 쿠키와 같이 브라우저에 중요한정보를 남기지 않는다.

또한  세션 아이디는 서버와의 통신이 끊겼을 때(예: 브라우저가 닫히거나 로그아웃 시) 만료되어 더 이상 사용할 수 없기에 이후에 클라이언트가 다시 서버에 접속하면 새로운 세션 아이디가 발급된다.

 

 

세션 방식의 단점 

서버에 세션 id가 저장이 되다 보니 많은 사용자가 서버에 접속하게 될시 서버에 메모리가 부족해지는 현상이 발생할수 있다.  이런 서버 부하를 막기 위해 로드밸런싱하게 될시  user1이 톰켓서버를 통해 세션 id값을 부여 받고 다시 요청을 했을때 그 요청이 원래 처음 세션 id값을 받았던 서버가 아닌 다른 서버로 로드밸런싱 될수 있다 그렇게 될경우 다른 서버에는 해당 user1에 세션 id값이 없다보니

로그인이 풀리는 상황이 발생하게 된다 . 

 

 

JWT(JSON Web Token)을 이용한 상태 유지 


 JWT?

jwt를 사용하면  세션 , 쿠키를 대신하여 의미있는 문자열 토큰을 발급 받게 된다 

 

 

토큰 생성 방식 

1.Header

헤더는 토큰 타입과 어떤 알고리즘이 쓰였는지를 나타냅니다.

{
  "alg": "HS256",
  "typ": "JWT"
}

 

 

2.payload

토큰의 두번째 부분은 클레임을 포함하는 payload입니다. 클레임은 일반적으로 사용자 및 정보가 담겨있습니다. 

- payload에 담긴 정보는 인코딩만 되어 있기 때문에 누구라도 디코딩하여 확인할 수 있으므로 중요한 정보를 담으면 안 됩니다.

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

 

3.signature(서명)

JWT는 서명으로 데이터 무결성을 보장한다. 서명은  헤더와 페이로드를 인코딩한 문자열과 비밀키를 조합하여 생성을 한다. 이때 서버측에서는 비밀키를 사용하여 서명을 생성 한다. 클라이언트측에서도 서명을 검증하기 위해 서버의 비밀키를 알고 있어야 한다.

 

 

 

서버에서는 시그니처로 생성된  문자열을  클라이언트에게 전달 하면  클라이언트는  전달 받은 JWT Token을 가지고 세션을 유지 합니다.

 

 

JWT 방식의 장점

 

JWT는 서버에 저장되어 관리되지 않기에 메모리 공간이 부족하지 않다.  JWT는 클라이언트 측에 저장이 되며 서버는 클라이언트가 보낸 JWT토큰을 검증한다.  로드밸런스 할시  세션을 서버 사이에 동기화해야 할 필요가 없다. 따라서 분산환경에서도 각각의 서버에서 독립적으로 JWT를 검증하고 처리할 수 있다.

 

JWT 방식의 단점 

JWT는 발급된 후에도 클라이언트에 의해 계속해서 전달될 수 있기 때문에, 세션이 끊겨도 JWT가 유효하다면 클라이언트는 다시 로그인을 하지 않아도 다른 API 엔드포인트에 접근할 수 있다. 그러므로  jwt 토큰이 탈취되었을 경우 누구나 해당 토큰의 권한을 가지고 서비스를 이용할 수 있다.

 

누구나 헤더와 페이로드의 내용을 볼 수 있기 때문에 보안에 위협이 될만한 정보나 개인정보가 있다면 노출될 수 있다는 단점도 있다.(그래서 그런 정보는 넣으면 안 됩니다) 이러한 이유로 보통 jwt토큰의 만료시간(exp)을 짧게 정하고 리프래시 토큰(Refresh Token)과 함께 사용해야 한다.

 

 

 

결론 

세션을 사용하여 보안성을 유지하면서   서버 메모리 부족 , 로드밸런스시 세션과 서버 사이 동기화 문제를 Redis를 통해 해결 할려고 한다.

Redis는 인메모리 데이터 저장소기에 , 세션과 같은 조회가 빈번하게 일어나는 경우 빠르게 조회하고 저장 할 수 있다. 또한  Redis는 클러스터 모드로 사용할 수 있기 때문에 , 로드밸런싱된 여러 서버에서도 세션 데이터를 공유 동기화가 가능하다.