JWT를 사용했을 때, DB나 Cache를 두지 않았다고 가정을 해보자.(완전히 stateless한 서버를 구성)
중복 로그인 처리
웹 서비스를 운영 중에 있을때, 사용자가 동시에 여러 곳에서 로그인을 할 수 없게 하려고 한다.
ex) 기존에 A가 로그인을 한 상태에서 B가 로그인을 시도하면 A를 만료시킴
만약 세션을 서버에서 관리하고 있다면 서버에 저장되어 있는 해당 사용자의 세션을 초기화시키면 된다.
그러나 JWT를 이용한다면 서버는 현재 아무런 정보가 없는 상황이다.
따라서, 위 예시에서 B가 로그인을 시도해도 중복 로그인인지 확인할 수 있는 방법이 없다.
(그렇다고 누군가 중복 로그인을 한 것 같다는 소식이 들려왔을 때 전체 토큰 세션을 날려버릴 순 없다...)
보통 만료시점을 넣어두지만 만료시점 전에는 해당 토큰을 임의로 만료시킬 수 없다.
따라서, JWT방식을 이용할 때 중복 로그인을 못하게 하려면 다른 방법이 필요할 것 같다...
(지금하는 프로젝트는 중복 로그인을 막을 이유가 없어서 찾아보진 않았다)
토큰 유출
개인 프로젝트라면 딱히 상관이 없겠지만, 데이터가 공유되는 서비스에서는(일반적으로 우리가 이용하는 웹 서비스)에서 JWT만으로 세션 관리를 하는 것은 좋아보이지 않는다.
만약 토큰이 유출되면 무분별한 사용이 가능한데, 임의로 막을수가 없다.
토큰이 유출이 되었을 때, 정보에 민감한 정보를 포함하고 있다면 더 큰일이다.
보통 JWT를 쓰는 곳은 토큰 방식으로 인증과 관련된 모든 처리를 하지는 않고, 세션 관리는 기존 방식을 유지하면서 토큰을 쿠키 정도의 역할로 많이 사용한다.
그렇다면 어떻게 해야할까?
당장 생각나는 것은, 대칭키 암호화 방식이 있다.
직관적으로 보호할 데이터에 대한 비밀번호를 정하고, 그 비밀번호로 암호화를 한다면 탈취를 당하더라도 비밀번호를 모르기 때문에 복호화를 하지 못한다.
JWT와 대칭키 암호화 방식을 적용하는 방식은 여러가지가 있다.
1. 서버에서 적용하는 방법
기본적으로 JWT 데이터는 사용자가 수정은 할 수는 없지만 보는 것은 가능하다.
그러나, 사용자가 보는 것도 불가능하게 만들 수 있다.
탈취를 당했을 때, 탈취범이 볼 수도 없으니까 이러한 취약점을 보완하기 위해 서버에서만 볼 수 있게 하는 것이다.
이러한 방식으로 서버에서 일부 데이터를 대칭키로 암호화 하는 방법이다.
그러면 토큰의 일부 데이터는 암호화 되어 있기 때문에 사용자는 알 수 없지만, 서버는 토큰을 받으면 어떤 데이터가 있는지 확인이 가능하다.
2. 클라이언트에서 적용하는 방법
개인정보를 모두 클라이언트에서 보관을 하고 있다고 가정을 해보자
그런데 클라이언트에서 개인정보를 저장한 파일을 탈취 당한다면, 문제가 될 수 있다.
위에서 언급했듯이 토큰을 수정하지는 못해도 보는 것은 가능하기 때문이다.
하지만, 여기에서도 클라이언트에서 대칭키로 암호화 할 수 있다.
본인만 알 수 있는 비밀번호를 설정하여 데이터들을 암호화 해두는 것이다.
그렇게 되면 탈취를 당하더라도 데이터를 보호할 수 있고, 인증 수단으로도 활용할 수 없다.