-
Token인증 방식(JWT)과 Session인증 방식Java 2023. 11. 13. 23:58
개요
이제까지 배웠던 로그인 방식은 세션에 저장하는 방식만 배웠기에 다른 인증 방법이 있는줄 몰랐는데, 세션 방식말고도 토큰 방식 인증인 JWT가 있다는 것을 알게 돼서 정리해보고자 한다.
HTTP의 특성
우선 로그인 인증방식으로 JWT와 Session을 알아보기 앞서서 왜 사용하는가를 알아볼 필요가 있다.
HTTP는 비연결성(Connectionless)와 무상태성(Stateless)라는 특성을 가진다.
비연결성(Connectionless)
HTTP는 연결을 유지하지 않는다. 라는 특성이 있다.
즉, HTTP는 서버와 클라이언트간 통신이 한 번 이뤄지고 나면 연결이 끊어진다는 것이다.
무상태성(Stateless)
HTTP는 상태를 유지하지 않는다. 라는 특성이 있다.
즉, HTTP는 첫번째 통신 이후 두번째 통신을 할 때, 첫번째 통신에 대한 정보를 가지고 있지 않는다.
이러한 HTTP의 특성으로 인해 사용자가 로그인 했다면, 다음 작업시 로그인을 반복적으로 요구하지 않도록 로그인 정보를 유지시켜야 한다.
세션(Session)
세션은 사용자의 정보를 서버의 메모리, 데이터베이스와 같은 서버의 자원들을 사용해서 사용자의 정보를 유지시키는 방법이다.
세션 인증 과정
1. 사용자가 로그인을 하게되면,
2. 서버는 사용자의 아이디 세션을 서버의 메모리에 저장시키고
3. 세션ID값을 보통 쿠키에 담아서 보내주게 된다.
4. 그리고 이후 요청부터는 세션ID가 담긴 쿠키를 같이 전달하고,
5. 해당 세션ID가 서버의 메모리와 맞게 저장되어 있는지 검사한다.
6. 인증이 완료되면 사용자의 요청에 맞는 응답을 보내준다.
장점
- 세션ID 자체는 유의미한 개인정보가 아니기 때문에 보안성이 높다.
- 서버가 클라이언트의 웹 브라우저에 의존하지 않아도 된다.
단점
- 세션을 DB에 저장해서 탐색하기 때문에 유저가 늘어날 수록 서버의 램이 과부하가 생길 수 있다.
- 로그인한 해당서버에서만 사용할 수 있기 때문에 서버를 추가하거나 하는 등의 확장성 이슈가 있다.
토큰(Token)인증 이란?
토큰은 클라이언트가 서버에 접속하게 되면 서버에서 클라이언트에게 인증되었다는 의미로 토큰을 부여한다.
해당 토큰은 고유한 토큰으로 클라이언트는 서버에 요청을 할 때마다 요청 헤더에 토큰을 심어서 보낸다.
서버에서는 클라이언트로부터 받은 토큰이 서버에서 제공한 토큰인지 일치여부를 체크해 인증과정을 처리한다.
세션 인증은 서버가 세션정보를 가지고 있어야하기 때문에 사용자가 많아질수록 서버에 대한 부하가 커질 수 있었다.
토큰 인증의 경우, 서버가 아닌 클라이언트(브라우저)에 저장되기 때문에 서버자원의 부담을 덜 수 있다.
토큰 자체에 데이터가 들어있기 때문에 클라이언트에서 받아 위조되었는지 판별만 하면 되기 때문이다.
대표적인 토큰 방식에는 주로 OAuth나 JWT가 있다. 해당 포스트에서는 JWT에 대해서만 정리하고 OAuth는 다음에 정리하고자 한다.
JWT
JSON Web Token의 약자로 인증에 필요한 JSON형태의 정보를 암호화 시킨 토근이다.
토큰 방식은 사용자가 로그인하면 서버에서 토큰을 발행해주고 브라우저의 저장소에 토큰을 유지시킨다.
JWT의 구조는 Header, Payload, Signature 세 가지로 ' . '(온점)을 기준으로 구분한다.
Header
헤더는 토큰의 타입과 암호화 할 해싱 알고리즘에 대한 정보가 있다.
Payload
인증에 필요한 정보에 해당하는 부분이다.
주로 클라이언트 고유ID, 유효기간 등이 포함된다.정보의 조각을 클레임(Claim)이라고 하며, Key-Value 형식으로 이루어져 있다.
페이로드에는 여러개의 클레임을 담을 수 있으며 공개, 비공개를 결정할 수 있다.
Signature
시그니쳐에는 위의 헤더와 페이로드를 합친 문자열을 서명한 값이다.
정확히는 인코딩된 Header와 Payload를 더한 뒤, 비밀키로 해싱하여 생성한다.
Header와 Payload는 단순 인코딩된 값이기 때문에 해커가 복호화하고 조작할 수 있지만, Signature는 서버측에서 비밀키가 유출되지 않는 이상 복호화할 수 없다.따라서 해커가 Header와 Payload를 위변조 한다면, Signature를 통해서 알 수 있게 된다.
JWT 인증 과정
1. 사용자가 로그인을 하게 되면,
2. 서버는 JWT를 발급하고
3. JWT를 브라우저에 보내준다.
4. 사용자는 요청과 함께 JWT를 보내고
5. JWT의 Signature를 검사하고 사용자 정보를 JWT를 통해 얻는다.
6. 사용자의 요청에 맞는 응답을 보내준다.
장점
- Header와 Payload를 가지고 Signature를 생성하여 데이터 위.변조를 막을 수 있다.
- 토큰기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능하다.(Facebook로그인 ,카카오톡 로그인 등)
- JWT는 발급한 후 검증만 하면 되기 때문에 stateless한 서버를 만들 수 있다.
단점
- 토큰이 브라우저 저장소에 저장되기 때문에 DB에서 사용자 정보를 수정한다면 토큰에 직접 적용할 수 없다.
- Payload는 디코딩하면 누구나 볼 수 있기 때문에 사용자의 정보(최소한의 정보라 하더라도) 해킹될 위험있다.
- 토큰을 탈취당하면 대처하기 어렵다. 토큰은 한 번 발급되면 유효기간이 만료될 때까지 악의적인 사용이 가능하다.
(쿠키가 악의적으로 사용되고 있다면, 해당 세션을 지워버리면 되지만,,,)
세번째 단점을 해결하기 위해 기존의 Access Token의 유효기간을 짧게 하고 Refresh Token이라는 새로운 토큰을 발급한다. 그렇게하면 Access Token을 탈취 당해도 상대적으로 피해를 줄일 수 있다.
RefreshToken
JWT의 단점을 해결하기 위해 AccessToken과 Refresh Token으로 이중으로 나눠 인증한다.
처음에 로그인했을 때 Access Token과 동시에 발급되는 Refresh Token은 Access Token보다 긴 유효기간을 가져서, Access Token이 만료됐을 때 새로 발급해주는 열쇠가 된다.
즉, Access Token의 유효기간을 짧게 만들고, 유효기간이 만료될 때마다 Refresh Token을 통해 새로운 Access Token을 만들어서 보안을 조금이라도 더 안전하게 한 것이다.
Refresh Token 사용 과정
2023-12-19 추가
토큰과 Session의 근간이 되는 쿠키에 대한 내용이 없어서 추가적으로 포스팅했습니다.
참고 블로그
'Java' 카테고리의 다른 글
@Transactional이란 무엇인가 (0) 2023.11.22 생성자 주입(Constructor Injection)을 권장하는 이유 (1) 2023.11.20 Early Return (0) 2023.11.18 JVM (0) 2023.11.16 MVC 패턴 (0) 2023.11.12