https://castle0312.tistory.com/18
[Node.js] JWT에 대해 알아보기
1. JWT이란? JWT Token 이란 JSON Web Token의 줄임말로 말 그대로 JSON 데이터를 가지는 토큰이다. 헤더, 페이로드, 시그니처로 이루어져 있습니다. 헤더 - 보통 헤더는 해당 토큰의 타입과 토큰을 암호화
castle0312.tistory.com
들어가기 전
이전 글에서 JWT에 대한 기본적인 내용을 알아봤으니 이번 글에서는 JWT를 어떻게 사용하는지 자세히 알아보겠다.
사용법 1 - token 하나만 발급
사실 이 방식은 그냥 토큰을 발급 받으면 유저가 그 토큰 하나만 가지고 있는 방식이라서 사용법이랄꺼 까지는 없다. 흔히들 가장 기본적으로 생각할 수 있는 그냥 로그인을 하거나 다른 인증을 거치면 서버에서 해당 유저를 판별할 수 있는 정보(아이디, 이메일 등)를 넣고 토큰을 만들어 다시 유저에게 주면 유저는 그 토큰 하나만을 가지고 주구장창 사용자 인증을 할때 사용하는 것이다.
장점
- 이 방식의 장점은 당연히 코드의 가독성과 코드 작성의 간편성이다. 다른 것 필요 없이 유저가 로그인을 요청하면 해당 유저에 대한 정보를 담고 토큰을 만들어 그 유저에게 준 다음 유저가 어떤 행동을 할 때마다 토큰을 검사하여 올바른 유저인지 확인만 하면 되기 때문에 코드의 가독성과 코드 작성의 간편성이 매우 좋아진다.
- 마찬가지로 프론트의 코드에서도 토큰이 하나만 있으므로 처리할 작업들이 매우 줄어든다.
단점
- 중간자 공격(Man-in-the-middle attack)에 매우 취약할 수 있다.
- 보안을 고려해 토큰의 유효기간을 짧게 설정할 시 유저의 불편을 초래한다.
보다시피 굉장히 간편한 방법이지만 그에 따라서 매우 치명적인 단점이 존재하므로 사실 잘 사용하는 방식은 아니다. 그럼 어떻게 토큰을 발급하고 사용해야지 이러한 단점을 보완하면서 토큰의 장점을 사용할 수 있을까? 이를 위해 나온 방법이 Access Token, Refresh Token을 활용한 방식이다.
사용법 2 - Access Token, Refresh Token
위에서 말했다시피 토큰을 하나만 사용하는 것은 치명적인 단점이 있다. 토큰의 특성상 발급을 하면 없애는 것이 불가능하기 때문에 중간자 공격을 당하면 해당 토큰의 유효기간이 지나기까지 공격자가 마음대로 접근할 수 있고 서버에서 이를 막을 방법이 없기 때문에 굉장히 위험하다. 이를 방지하고 위험도를 최소화 하는 방법으로 Access Token과 Refresh Token을 만들어서 사용하는 방식이 있다.
먼저 Access Token에 대해 말하면 이름에서 알 수 있듯이 유저가 서버로 접근할때 즉 API 요청시에 사용되는 토큰으로 보통 짧은 유효기간을 주어 토큰을 탈취 당하더라도 위험도를 최소화 하는 목적으로 사용한다.
Refresh Token을 Access Token을 재발급(Refresh)할때 사용하는 토큰이다. Refresh Token은 유효기간을 상대적으로 길게 가지며 해당 기간동안에 Access Token이 만료되면 유저가 Refresh Token을 서버에 전달하여 사용자를 인증하고 통과하면 다시 Access Token을 발급하여 주는 방식이다.
여기서 보통 의문을 가질만 부분이 그럼 Refresh Token은 서버가 뭘 보고 다시 Access Token을 발급해주는지 의문을 가질 만한데 이건 보통 Refresh Token을 발급할때 서버도 같은 토큰을 DB에 저장하여 보관하기 때문에 가능하다. 즉 유저의 Refresh Token과 서버가 가지고 있는 Token을 비교하여 맞으면 재발급이고 다르면 거부당한다.
장점
- Access Token을 이용해서 API요청을 하기 때문에 Access Token이 탈취 당하더라도 유효기간이 짧기 때문에 피해를 최소화 할 수 있다.
- 여전히 JWT를 사용하는 것이기 때문에 세션에 비해 DB에 접근하는 횟수가 많이 줄어든다.
단점
- 토큰 2개를 사용하기 때문에 코드가 좀 늘어난다.
- Refresh Token의 경우 서버에 저장을 해야 되기 때문에 완벽하게 stateless하지는 않다.
- 단점이라긴 그렇지만 이 방식을 사용해도 중간자 공격에 완벽하게 대응할 수 있는 것은 아니다. 단지 공격을 당하더라도 피해를 최소화하는 것이다.
전체적인 순서를 정리하자면
- 로그인 과정을 통과하면 서버에서 해당 유저의 정보를 담은 Access Token 과 Refresh Token을 발급하여 유저에게 준다.
- 유저는 토큰을 발급 받은 후 API요청을 할 때마다 Access Token을 사용하여 사용자 인증을 한다.
- Access Token을 사용하다가 해당 토큰의 유효기간이 지나 API요청이 거부될 경우 Refresh Token을 서버로 다시 전송한다.
- 서버는 Refresh Token이 오면 토큰을 검사하여 토큰이 유효하면 Access Token을 재발급하여 다시 보낸다.
- 유저는 다시 받은 Access Token으로 다시 API요청을 한다.
이러한 프로세스를 가진다.
Refresh Token 탈취?
그럼 이렇게 생각 할 수도 있다. Access Token도 탈취 가능성이 있는데 그럼 Refresh Token은 탈취 당할 걱정할 필요가 없는건가?
결론부터 말하자면 Refresh Token도 탈취 당할수 있다.
대신 Access Token에 비해 서버로 전송되는 횟수가 확연히 적기 때문에 가능성이 낮을 뿐이다.
그러나 가능성이 적을 뿐이지 탈취 당하면 오히려 더 위험한게 Refresh Token이다. 그렇기 때문에 제시된 방법이 있는데 바로 RTR(Refresh Token Rotation)이다.
Refresh Token Rotation?
이 방식은 Access Token을 재발급 할때 Refresh Token도 재발급하여 같이 유저에게 제공하는 방식이다.
이런 방식을 사용하면 일반적인 Refresh Token보다 보안적인 측면으로는 우수해지지만 문제는 Access Token 재발급때마다 같이 재발급해야하기때문에 추가적인 로직이 생기고 크게 보면 세션 방식과 비슷해지고 Access Token과 유효기간을 공유한다는 문제가 생긴다.
그럼에도 불구하고 보안적인 이득이 있고 세션보다는 부하가 덜 생기기 때문에 고려해볼만한 방식인거 같다.
정리
- JWT는 그냥 토큰 하나만 사용할 수도 있지만 보안을 위해서 보통 2개로 사용하는 방식을 채택한다.
- 그 2개의 토큰이 Access Token, Refresh Token이다.
- Access Token은 API요청시 사용자 인증 용이고 Refresh Token은 Access Token의 유효기간이 만료되었을 시 재발급 용도이다.
- 하지만 이 방식에도 보안적인 취약점이 있기 마련이고 이를 위해서 RTR이라는 방식도 존재한다.
- 실제 사용시에는 프로젝트의 특성에 맞게 세션을 사용하던, RTR을 사용하던 그냥 일반적인 Access Token, Refresh Token 방식을 사용하던 판단해서 맞게 사용해야된다.
'Node.js(Express)' 카테고리의 다른 글
| [Node.js] SNS 만들기 - Multer로 Multipart/Form-Data로 사진 전송 게시글 작성 (0) | 2024.02.02 |
|---|---|
| [Node.js] SNS 만들기 - Nodemailer를 이용한 사용자 인증 (0) | 2024.01.22 |
| [Node.js] JWT에 대해 알아보기 (0) | 2024.01.18 |
| [Node.js] SNS 만들기 - Controller 만들기 (0) | 2024.01.18 |
| [Node.js] SNS 만들기 - Model 만들기 (0) | 2024.01.18 |