이전 포스팅에서 JWT(Json Web Token)의 개념과 구조에 대해서 알아보았습니다. 이번 포스팅에서는 JWT의 보안 전략과 각각의 장단점을 알아보도록 하겠습니다.
AccessToken 사용
JWT에서는 기본적으로 AccessToken을 제공한다. 서버가 클라이언트에게 발급해주는 AccessToken은 클라이언트의 저장공간에 저장된다. 그러므로 AccessToken은 데이터베이스나 파일 등에 저장할 필요가 없고 메모리상에서 인증을 처리하기 때문에 추가적인 I/O 작업이 필요가 없다. 이러한 이유 때문에 한번 발급된 AccessToken은 서버 측에서 만료시킬 수 없어 특정 사용자의 접속을 강제로 만료시킬 수 없다. 일반적으로 클라이언트 측의 저장공간에서 토큰을 삭제하는 방법을 통해 특정 사용자의 접근을 막는다. 서버 측에서는 AccessToken의 만료기간 설정을 어떻게 하는지에 따라 다른 전략을 사용할 수 있다.
만료기간을 짧게 설정
토큰의 만료기간을 30분 내의 짧은 기간으로 설정하는 경우의 장단점은 아래와 같다.
장점
- 토큰이 탈취되더라도 빠르게 만료된다.
단점
- 사용자가 자주 로그인을 해야합니다.
- 사용자가 서비스를 이용하던 도중 토큰이 만료되어 다시 로그인을 해야 하는 경우가 생길 수 있다.
만료기간을 길게 설정
토큰의 만료기간을 2주에서 한 달 정도로 길게 설정하게 되었을 때 장단점은 아래와 같다.
장점
- 사용자가 자주 로그인할 필요가 없다.
단점
- 토큰이 탈취되었을 경우 긴 만료기간 동안 제약 없이 사용 가능하다.
Sliding Sessions 전략과 함께 AccessToken 사용
AccessToken만 사용할 경우 보안성과 편의성에 대한 트레이드오프가 존재한다. 이러한 고민의 해결책으로 나온 것이 Sliding Sessions 전략이다. 이 전략은 세션을 지속적으로 이용하는 유저에게 자동으로 만료 기간을 늘려주는 방법이다. 주로 유효한 AccessToken을 가진 클라이언트의 요청에 대해 서버가 새로운 AccessToken을 발급해주는 방법을 사용한다. 매 요청마다 새로운 토큰을 발급할 수도 있지만 게시글을 작성 시작할 때처럼 특정 작업을 시작할 때 토큰을 발급해주는 전략을 사용하는 것도 괜찮은 방법이다. 또한 토큰의 iat(토큰 발급 시간)을 참조해서 갱신을 하는 방법도 있다.
장점
- 사용자가 로그인을 자주 할 필요가 없다.
- 글을 작성하거나 결제를 하는 등 세션 유지가 필요한 순간에 세션이 만료되는 문제를 어느 정도 보완할 수 있다.
단점
- 접속이 주로 단발성으로 이루어지는 서비스의 경우 Sliding Sessions 전략의 효과가 크지 않다.
- 긴 만료 기간을 갖는 AccessToken을 사용하는 경우 로그인을 전혀 하지 않아도 되는 경우가 발생할 수 있다.
AccessToken과 RefreshToken을 사용
사용자가 로그인할 때 서버는 짧은 만료기간을 갖는 AccessToken과 긴 만료 기간을 갖는 Refresh Token을 함께 발급한다. 주로 AccessToken은 30분 내외, RefreshToken은 2주에서 한 달 정도의 만료 기간을 갖는다. 클라이언트는 AccessToken이 만료되었다는 오류를 받으면 따로 저장해두었던 RefreshToken을 통해 새로운 AccessToken의 재발급을 요청한다. 서버는 유효한 RefreshToken을 받으면 새로운 AccessToken을 발급하고, 만료된 RefreshToken을 받으면 오류를 반환해 사용자에게 로그인을 요청한다.
RefreshToken은 AccessToken과는 다르게 서버의 저장공간에 따로 저장해서 검증해야 한다. 이것은 추가적인 I/O 작업이 필요하다는 의미이고 이것은 I/O작업이 필요 없는 빠른 인증 처리를 장점으로 내세우는 JWT의 스펙에 포함되지 않는 부가적인 기술이다.
RefreshToken은 탈취되어서는 안 되므로 클라이언트는 보안이 유지되는 공간에 이를 저장해두어야 한다. RefreshToken은 서버에서 따로 저장하기 때문에 강제로 토큰을 만료시키는 것이 가능하다.
장점
- AccessToken의 짧은 만료기간으로 인해 탈취되더라도 제한된 기간만 접근이 가능하다.
- 사용자가 로그인을 자주 할 필요가 없다.
- RefreshToken이 서버에 따로 저장을 하고 있기 때문에 강제로 만료시킬 수 있다.
단점
- 클라이언트는 AccessToken의 만료에 대한 연장 요청을 구현해야 한다.
- RefreshToken의 만료 기간 자동 연장이 불가능하다.
- 서버에 별도의 저장공간을 만들어야 한다.
Sliding Sessions 전략과 함께 AccessToken과 RefreshToken을 사용
AccessToken의 Sliding Sessions 전략과는 달리 이 전략에서는 RefreshToken은 만료 기간을 늘려준다. RefreshToken의 만료기간이 늘어나기 때문에 AccessToken + Sliding Sessions 전략과는 달리 빈번하게 만료 기간의 연장 요청을 할 필요가 없다. 반면 사용자가 접속을 빈번하게 하지 않더라도 RefreshToken의 만료기간이 늘어나기 때문에 휴대폰이 탈취되는 등의 경우에 지속적인 이용이 가능하게 된다. 이런 경우 확실한 인증이 필요한 상황에서 비밀번호를 한번 더 물어본다거나, 비밀번호 변경 요청 시 서버에서 강제로 RefreshToken을 만료 처리를 함으로써 해결할 수 있다.
장점
- RefreshToken의 만료 기간에 대한 제약을 받지 않는다.
- 세션 유지가 필요한 순간에 세션이 만료되는 문제를 방지할 수 있다.
단점
- 서버에서 강제로 RefreshToken을 만료시키지 않는 한 지속적인 사용이 가능하다.
- 추가적인 인증이 필요한 경우에 대한 보안 강화가 필요하다.
결론
JWT를 사용하였을 때 얻는 장점도 많지만 여러 가지 문제점들도 존재한다. 토큰 탈취에 대한 취약성, 서버의 클라이언트 제어 불가, 빈번한 로그인 요청 등이 있을 수 있는데 이러한 문제점들은 Sliding Sessions 전략이나, Refresh Token을 사용함으로써 해결할 수 있다. 하지만 이러한 전략들 역시 추가적인 I/O가 발생하여 성능 감소로 이어질 수 있고, 편의를 위해서 보안이 취약해지는 상황들이 발생할 수 있다.
보안에 민감한 서비스를 다루고 있는 경우 비밀번호를 한번 더 묻는 것은 문제가 되지 않지만, 게시글을 작성하는 도중 계속 비밀번호를 물어보게 된다면 사용자들은 불편을 겪을 것이다. 보안성과 편의성을 모두 얻는 것은 불가능할 수 있으므로 해당 서비스의 특성을 고려해 보안성을 높일지, 사용자의 편의성을 높일 지 결정해야 할 것이다.
이번 포스팅에서는 JWT에서 사용할 수 있는 다양한 보안 전략에 대해 알아보았습니다. 다음 포스팅에서는 직접 SpringSecurity와 Redis를 통해 AccessToken과 RefreshToken을 사용하는 전략을 사용하여 JWT를 직접 구현해보도록 하겠습니다.
참고
https://tansfil.tistory.com/59
https://blog.ull.im/engineering/2019/02/07/jwt-strategy.html
'Web' 카테고리의 다른 글
캐시(로컬 캐시 & 글로벌 캐시)에 대해 알아보자! (0) | 2023.05.21 |
---|---|
JWT(Json Web Token)에 대해 알아보자! (0) | 2022.09.04 |
서버 기반 인증과 토큰 기반 인증에 대해 알아보자! (1) | 2022.07.24 |