이전에 프로젝트에서 JWT(JSON Web Token)을 많이 사용하였다.
JWT의 기본 개념과 왜 Session 방식의 대체로 사용되는지 알아볼 것이다.
JWT로 만들어지는 Access_Token & Refresh_Token의 개념과 활용에 대한 글이다.
JWT란 웹표준 (RFC 7519)으로써, 두 개체에서 JSON 객체를 사용하여 가볍고 자가수용적인 방식으로 정보를 안정성 있게 전달한다.
#cf) 여기서 "자가수용적"이란 JWT 가 필요한 모든 정보를 자체적으로 갖고있다는 것을 의미 (Signature 검증영역 존재)
JWT 는 3가지 영역으로 나뉜다.
Header(헤더) , payload(내용) , signature(서명)
header = base64_encode(headerJSON)
payload = base64_encode(payloadJSON)
Signature = base64_encode(HMAC_SHA256(header+"."+payload,secret))
JWT = header + "." + payload+"."signature
JWT을 활용할 때,보통 Access Token 과 Refresh Token을 활용한다.
난 이전 프로젝트를 진행할 때, Access Token 만을 활용하였고, 유효시간 또한 마음대로 하루로 정하였다. 이는 Access Token 탈취 됬을 때, 보안적으로 굉장히 위험한 방식이였다.
이런 위험을 최소화 하기 위해서 사용하는 방식은 다음과 같다.
즉, Access Token이 탈취되더라도 자원에 접근할 수 있는 시간이 적기 때문에, 쓸모없는 토큰이 되는 것이다. Refresh Token은 Access Token을 재발급하기 위한 용도로, DB에 따로 저장한다.
만약 내가 저장한다면, Redis에 저장하며 읽기,쓰기 속도에 유리함을 줄 것 같고, TTL(Time to Live)을 지정하여, 알아서 삭제될 수 있도록 설정해줄 것 같다.
우선 JWT를 활용하였을 때, 자체적으로 유저정보가 담겨 있기 때문에, DB에 조회를 하지 않아도 된다는 장점이 있고, 서버가 여러대일 때의 세션 문제를 해결하는 방식이 되었다.
다음으로 Access Token 과 Refresh Token이 어떤 방식의 순서로 작동하는지 알아보자
다음 그림 4번 과정에서
로그인 성공한 Client에게 Access Token 과 Refresh Token을 전달하는 것을 확인할 수 있다.
Refresh Token을 사용자에게 어떻게 제공할 것인가에 대한 여러가지 의견이 있어서 작성해 본다.
카카오는 재작년 Refresh 토큰을 클라이언트에게 반환하는 것을 보안상의 이유로 막았고, 추가의 인증과정을 통해 Refresh token을 발급받도록 변경하였다.
Refresh Token을 좀 더 보안상 안전하게 저장하고 관리할 것인지에 대해 이야기가 많다. Refresh Token은 유효기간이 대체적으로 길기 때문에 탈취당하면 보안의 위험성이 커지기 때문이다.
Refresh Token을 Client에게 어떤방식으로 내려줄 것인가 그리고 어떻게 Client에서 보관할 것인가 두 가지가 큰 이슈인 거 같다.
지금 내 생각으로는, Client 에 저장할 때에는, HttpOnly와 Secure 설정이 된 쿠키에 저장하고, Client에 내려줄 때에는, RefreshToken이 저장된 DB의 (Index or Primary key )를 암호화해서 넣어두고, Refresh Token으로 Access Token 발급할 때, 복호화해서 Refresh Token이 유효한지 확인할 것 같다. 또, Refresh Token을 한번 사용했다면 다시 만들어서 db에 새로 저장하고 새로 내려줄 것 같다.
https://llshl.tistory.com/32
https://doogle.link/jwt-%ED%98%B9%EC%9D%80-oauth2-%EC%9D%98-refresh-%ED%86%A0%ED%81%B0%EC%9D%84-%EC%96%B4%EB%94%94%EB%8B%A4-%EC%A0%80%EC%9E%A5%ED%95%B4%EC%95%BC-%ED%95%A0%EA%B9%8C/