카테고리 없음

[인증/인가] 쿠키세션 방식과 JWT 방식

Mon Groy 2024. 9. 2. 23:43

한 서버에서 데이터를 받기 위해서는 인증과 인가를 거치도록 하는 경우가 있다

 

인증(Authentication) / 인가(Authorization) 의 차이는?

 

인증은 해당 서버를 이용하기 위해 회원으로 등록한 유저임을 확인받는 것

인가는 인증된 유저가 데이터를 사용할 수 있도록 허가하는 것

 

얼핏 보기에 서버와 유저가 데이터를 주고 받기 때문에 연결이 된 것으로 인식이 되어지지만

사실은 쿠키세션 방식이나 JWT 방식을 통해서 Connection Statless 를 유지하고 있다

 

*Statless 는 유저의 정보를 서버가 계속해서 가지고 있지 않는 상태

 

그렇다면 쿠키세션 방식과 JWT 방식이 무엇이길래

연결을 유지하지 않고도 데이터를 주고받도록 인증과 인가를 거치도록 할 수 있는 것일까?

*JWT = JSON Web Token


쿠키-세션 방식

 

유저가 처음 회원가입을 진행 한 후 로그인을 한다

- 로그인을 요청하면 서버에서는 DB에서 요청한 유저를 찾아 회원임을 확인하고, 세션을 발급해준다

- 그와 동시에 세션 저장소에 해당 세션을 저장하도록 하며,

- 세션을 받은 유저는 원하는 데이터를 요청할 때마다 쿠키에 해당 세션을 담아 보낸다

- 서버에서는 전달받은 쿠키에서 담겨있는 세션을 찾은다음

- 세션 저장소에 일치하는 세션이 있는지 확인한다

- 확인이 될 경우 원하는 데이터를 제공한다

 


JWT 방식

 

유저가 처음 회원가입을 진행한 후 로그인을 요청 한다(인증 요청)

- 로그인을 요청하면 서버에서는 DB에서 요청한 유저를 찾아 회원임을 확인하고, JWT를 발급해 준다(인증) 

- 이 때 서버는 JWT를 보관하지 않는다 ***

 

- 유저는 받은 JWT를 저장소에 보관하며

- 데이터를 요청할 때마다 저장했던 JWT를 함께 보낸다

- JWT 를 따로 저장하지 않기 때문에 "검증"이라는 절차를 거친다

- 검증이 되면 유저가 원하는 데이터를 내어준다 (인가)

 


(JWT 방식을 이용하기까지)

쿠키-세션 방식을 최대한으로 사용한 방법들

 

서버가 한 대인 경우라면 세션 저장소가 하나여도 문제가 없으나,

여러가지 문제로 서버가 한 대만 사용하는 경우가 없다고 생각하고 아래의 방법에 대해 이해해 보자

*위에서 유저라고 칭한 것을 클라이언트로 변경함

 

- 클라이언트가 여럿 들어오는 경우, 한 서버보다 여러 서버에서 각각 나눠서 받는 것이 효율적일 것이다

- 그렇기 때문에 각 서버에서 각 클라이언트의 인증과 인가를 처리하는데,

- 각 서버가 각각 세션 저장소를 가지고 있다면?

- 인증을 받았던 클라이언트가 인가를 받을 때도 항상 그 서버에 요청을 해야만 다시 인증을 받을 필요가 없어질 것이다

- 그렇다면 과연 효율이 좋을 수 있을까?

- 그렇지 못하기 때문에 요청이 들어오는대로 클라이언트의 요청을 받게 되는데, 각각 세션 저장소를 가지고 있다고 가정했기 때문에, 들어온 클라이언트의 요청을 처리하기 위해서 새로 인증을 거쳐야만 하는 이상한 상황이 계속 될 것이다

*로드 밸런서가 클라이언트들을 서버에 분담시키지만 여기서는 생략함

 

 

이를 해결하기 위한 방법

 

첫 번째 - 세션 저장소를 모든 서버에서 공유하는 방법

두 번째 - JWT를 사용하는 방법

 

첫 번째 방법은 세션 저장소에서 단순히 일치하는 정보를 찾으면되지만

두 번째 방법은 (따로 데이터를 저장하는 형태가 아니기 때문에) JWT를 검증하기 위한 동일한 Key 가 존재해야 한다

이를 Secret Key 라고 부른다

 


JWT 를 이용하는 절차(흐름, 알고리즘)

 

- 클라이언트 로그인 성공

- "로그인 정보" 를 (Secret Key로 암호화 하여) JWT 생성

- 생성한 JWT 를 직접 생성한 쿠키에 담아 클라이언트에 전달

* 전달 방법은 개발자가 정하며 **전달하는 위치는 정해져 있음

- 전달받은 JWT를 데이터 요청시마다 함께 보내옴

- 서버에서는 보내온 쿠키에 들어있는 JWT를 찾아서

- JWT를 Secret Key로 디코딩하여 확인함 (1. 위조여부, 2. 유효기간)

 


JWT 이용 장점

- 사용량이 많은 경우 과부하 방지

 

JWT 이용 단점

- 복잡한 로직

- secret 키를 탈취당할 경우 jwt 조작 가능


JWT의 구성(디코딩했을 때 얻는 정보: Header, Payload, Verify Signature)

 

part 1. Header ("alg", "typ")

* typ 은 보통  HMAC SHA256 혹은 RSA 사용

 

 

part 2.  Payload (  jwt 전자서명의 메타데이터)

클레임을 담고 있는데, 분류하면 registered claim 와 custom claim 으로 나눌 수 있음

* registered claim 는 예약된 형식이 존재

  • iss (issuer): Issuer of the JWT
  • sub (subject): Subject of the JWT (the user)
  • aud (audience): Recipient for which the JWT is intended
  • exp (expiration time): Time after which the JWT expires
  • nbf (not before time): Time before which the JWT must not be accepted for processing
  • iat (issued at time): Time at which the JWT was issued; can be used to determine age of the JWT
  • jti (JWT ID): Unique identifier; can be used to prevent the JWT from being replayed (allows a token to be used only once)

7개의 명세가 존재하며 필요에 따라 jwt 의 payload 에 추가하면 됨

** custom claim 은 예약된 형식의 클레임이 아닌 인증 절차의 특성에 따라 커스텀하게 추가할 수 있는 클레임

 

 

part3. Verify Signature( 헤더와 페이로드를 암호화한 결과)


 

 

Git bash 프로그램을 실행하여

openssl rand -base64 64

를 입력하면 JWT_SECRET_KEY 를 얻을 수 있음

 

복사 Ctrl + insert

붙여넣기 Shift + insert

 


 

JWT를 위한 대표적인 라이브러리는 jjwt와 java JWT가 있는데 JAVA 진영에서  jjwt가 더 많이 사용되고 있음


클래스 분류

 

  • JWT 정의하기 (JWT 생성과 소멸, 가져오기, 확인하기 >> 토큰을 통한 사용자 정보 얻기)
  • JwtAuthenticationFilter 설정하기 (클라이언트가 로그인시 사용, 정의된 JWT 를 생성하는 과정에 넣음)
  • JwtAuthorizationFilter 설정하기 (클라이언트가 데이터 요청시 사용, 쿠키에서 JWT를 가져와서 확인할 때 정의된 JWT를 넣음)
  • SecurityConfig 설정하기 (Security >> AuthenticationFilter >> AuthorizationFilter 순서도 설정해야 하므로 4번째)

참고

 

* 전달 방법은 개발자가 정하며 **전달하는 위치는 정해져 있음

https://hohodu.tistory.com/entry/JWT-JWT%EB%8A%94-%EC%96%B4%EB%94%94%EC%97%90-%EC%A0%80%EC%9E%A5%ED%95%A0%EA%B9%8C

 

[JWT] JWT는 어디에 담아 클라이언트와 요청/응답할까

고민 과정 상황 Access Token과 Refresh Token 발급하고 클라이언트에 어디에 담아 응답을 줄지 고민을 했다. 마찬가지로 클라이언트가 서버에 요청을 보낼때는 어디에 Access Token을 담아야 서버가 사용

hohodu.tistory.com

 

JWT의 구성(디코딩했을 때 얻는 정보)

https://westlife0615.tistory.com/111

 

json web token (JWT)

개요 jwt 는 json web token 의 약자로, 표준적으로 통용되는 인증 방식 중 하나입니다. jwt 의 이름은 json 과 web 을 포함하는데요. json 이 포함된 이유는 전자 서명을 생성 과정에서 json 형식을 사용되

westlife0615.tistory.com