session 기반 인증
클라이언트가 로그인을 하면 서버는 사용자 정보를 확인 후 저장소에 사용자 정보와 세션 ID를 매핑해 저장한다. 세션 ID를 쿠키로 클라이언트에게 전달해 준다. 클라이언트는 쿠키에 저장된 세션 ID를 활용하여 서버에 요청하면 된다. 서버는 일치하는 세션 ID를 검증하고 획득한 유저정보를 통해 응답값을 준다.
장점
- 사용자의 인증 정보를 서버에서 저장하고 클라이언트는 세션 ID만 저장하므로 보안에 좋다.
- 강제 로그아웃 시키는 것이 간단하다. 저장소에 세션 ID를 만료시키거나 삭제하면 되기 때문이다.
단점
- 서버에서 세션 정보를 관리한다는 점이다! 요즘엔 브라우저를 종료하더라도 로그인을 유지하는 추세이기 때문에 로그인했던 사용자를 모두 저장소에 저장하고 있고 이 사용자가 늘어날수록 과부하가 올 수 있다.
이런 단점을 보안해서 등장한 것이 jwt이다!
jwt 기반 인증
클라이언트가 로그인을 하면 서버는 사용자 정보를 확인 후 payload에 사용자 ID 등 필요한 정보를 넣고 토큰을 발급한다. 클라이언트는 이를 로컬 혹은 브라우저에 저장하고 jwt를 이용하여 서버에 요청하면 된다. 서버는 jwt를 검증 후 응답한다.
session과 jwt의 가장 큰 차이점은 session은 저장소에 사용자 정보를 저장하고 jwt는 토큰 안에 사용자 정보를 저장한다는 점이다.
jwt의 구조
jwt(json web token)은 헤더(header), 페이로드(payload), 서명(signature)으로 이루어져 있다.
- 헤더(header) - 토큰의 타입과 알고리즘 정보
- 페이로드(payload) - 필요한 정보(토큰 만료시간, 사용자 ID, 접근권한 정보 등)
- 서명(signature) - 헤더와 페이로드 값을 특정 알고리즘으로 서명하여 서명을 만든다.
헤더와 페이로드는 누구나 볼 수 있기 때문에 중요한 정보를 담으면 안된다!
서명은 secret key를 모르면 복호화할 수 없다. A가 토큰을 조작하여 payload에 id를 다른 계정으로 변경해 요청을 보내면 서버는 서명을 검사해 유효하지 않은 토큰으로 판단한다. (A의 서명에 payload에는 다른 계정 정보가 있기 때문에)
장점
- 세션과 달리 저장소에 값을 저장하지 않아 서버의 부담이 적고 토큰 자체만으로 필요한 정보를 갖고 있어 좋다.
단점
- 서버가 토큰을 관리하지 않아 약탈되었을 때 토큰 만료까지 토큰을 무효화시킬 수 없어 대응이 어렵다.
이를 보완하기 위해 토큰의 유효시간을 짧게 생성한다.(30분 정도).하지만 유효기간이 짧다면 사용자는 계속해서 로그인이 풀려 다시 로그인을 해야 하는 불편함이 있다.
그래서! 로그인 시 토큰(accessToken)과 함께 refreshToken를 함께 발급한다. acessToken은 인증에 사용되고 refreshToken은 유효시간이 짧은 accessToken을 재발급하기 위한 용도로 사용한다. refreshToken은 사용자 정보와 함께 저장소에 저장해 둔다. 클라이언트에서 accessToken과 refreshToken으로 요청을 하고 서버는 accessToken 만료 시 refreshToken을 확인해 유효한 경우 accessToken을 새로 발급해 준다. refreshToken이 유효하지 않은 경우(만료 또는 저장소에 토큰과 다른 경우 등)에는 refreshToken을 만료시켜 로그아웃 처리한다.
자..! 그럼 jwt의 장점으로 저장소에 값을 저장하지 않고 jwt 자체만으로 유효성 검증을 할 수 있어서 좋다고 했다. 하지만 refreshToken을 사용하면 저장소에 저장하게 되고 jwt의 장점이 조금은 사라지게 된다..
결론!!
그래서 session과 jwt 중에 뭐가 옳다!! 뭐가 무조건 더 좋다!! 이런 건 없고 각자 상황에 맞는 인증 방식을 선택해서 사용하면 좋을 거 같다 ㅎㅎ
'IT' 카테고리의 다른 글
React Query (+custom hook으로 사용하기) (0) | 2024.01.15 |
---|---|
react와 vue 비교(데이터 바인딩과 데이터 흐름) (0) | 2024.01.05 |
Storybook createPortal 관련 에러 (Error: Target container is not a DOM element.) (1) | 2023.11.02 |
Storybook에서 SVGR 설정 (0) | 2023.10.31 |
[TIL] filter와 find의 차이점 (0) | 2022.03.07 |