JWT를 이용한 로그인과 동아리 회원 인증

김지수
모던 애자일
Published in
6 min readFeb 6, 2022

--

본 글에서는 동그라미 서비스에서 어떻게 JWT를 이용하여 회원 인증을
구현 하였는지 기술하고자 한다.

쿠키, 세션, JWT 이 세가지 개념들이 묶여서 설명되는건 많이들 알고 있을 것이다.

HTTP는 stateless하다는 특징을 갖고있다. 상태를 저장하지 않는다는 이러한 HTTP의 특성을 보완하고자 쿠키, 세션 등을 사용한다.
이러한 상태 저장 기능을 이용하기 때문에 어떤요청을 할 때마다 로그인을
해야 하는 귀찮은 상황을 덜어낼 수 있다.
쿠키와 세션은 거의 비슷하나 어디에 데이터를 저장하는지가 가장 큰 차이점이라고 할 수 있다.

자세한 내용은 해당 자료 참고:https://devuna.tistory.com/23

쿠키의 보안문제, 세션의 메모리 차지 문제 등이 제기 되면서 요즘 많이
사용하는 방식이 JWT인증 방식이다.

JWT(Jason Web Token)은 Json 포맷을 이용하여 사용자에 대한 속성을
저장하는 Claim 기반의 Web Token이다.

오늘은 JWT 구현에 대해 자세히 다룰 예정이라 JWT에 대한 자세한 내용은
다음 자료를 참고 바란다.

https://blog.naver.com/wltn5012/222455577639
https://www.youtube.com/watch?v=1QiOXWEbqYQ

필자는 서비스를 개발하면서 로그인 인증과 동아리 원 회원인증에 JWT를
이용했다. 간단하게 로직을 표현해보면

1. 클라이언트가(프론트엔드) 서버에 로그인 요청(POST)을 한다.
2. 서버는 해당 요청의 아이디와 비밀번호를 확인한다.
3. 아이디와 비밀번호가 존재한다면 JWT를 발급한다.
4. 발급한 JWT와 함께 성공 응답을 전송한다.
5. 클라이언트는 JWT를 따로 저장한다.
6. 로그인이 필요한 요청은 JWT토큰을 헤더에 담아 전송한다.
7. 서버는 헤더의 토큰 값을 확인하고 서버에서 생성한 토큰이 맞다면 요청에 대한 로직을 수행한다.

다음은 JWT 생성과 인증을 위한 코드이다.

payload는 누구든 볼 수 있기 때문에 보안이 필요한 정보는 절대 들어가선
안된다
. 또한 payload에 너무 많은 데이터를 넣을 경우 헤더가 무거워져
오버헤드가 발생할 수 있기 때문에 자주 사용하는 정보만 신중히 넣는다. ​

JWT의 유효시간

signature에 보면 만료기간은 ‘1d’ 즉, 하루로 되어있는 것을 확인할 수 있다.
사실 토큰 유효 시간을 길게 해서 좋을게 없다. 만약 토큰을 탈취 당한다면
토큰의 유효 시간이 만료되기전까지 손놓고 기다릴 수 밖에 없기 때문에
유효시간은 되도록 짧게 하는게 좋다.

하지만 유효시간이 짧아지면 사용자는 자주 로그인을 해야 하는 번거로움이 발생한다.

이러한 문제를 해결하기 위해 access토큰과 refresh토큰을 사용하기도 한다. 이 방식은 2개의 토큰을 발급받아 사용하는 방식인데 access 토큰 유효시간은 몇 시간 단위로 짧게 만들고 refresh토큰의 유효시간을 몇 주 단위로 길게 잡아 놓고 평상시에는 access 토큰으로 인증을한다.
access토큰 만료 시 refresh토큰으로 다시 access토큰을 발급받는 방식으로
이루어진다.

하지만 이 방식도 결국 유효시간이 훨씬 긴 refresh토큰을 탈취당하면 의미가 없다는 의견도 보였고, 이 방식으로 구현하진 않았다.

로그인 인증​

로그인이 성공한 경우 createJWT함수를 이용해 토큰을 생성하여 응답 body에 실어 보내주게 되는데 이제 토큰 생성을 어떻게 인증에 활용하는지 확인해보자.

우선 로그인 인증 미들웨어를 생성해 로그인 시 처리할 수 있는 API 요청에는 이 미들웨어를 모두 넣어 준다. 이제 어떤 API 요청을 처리하기 전 미들웨어를 실행해 토큰의 유효성을 검사하게 된다.

req.headers.authorization

필자는 클라이언트가 헤더에 ‘x-auth-token’에 토큰을 넣어 요청을 보내면
이 값을 검사하도록 구현하였다.
사실 ‘x-auth-token’이라는 키를 만들어줄 필요가 없다. req.header에는 인증을 위한 authorization이라는 키값이 존재하는데 이 부분에 토큰을 넣어
요청을 보내면 된다.

​포스트맨에서 확인해보면

authorization에 토큰을 넣어 준다.

그러면 이처럼 자동으로 헤더의 authorization의 키값으로 토큰이 지정된다.​

만약 ‘x-auth-token’에도 토큰을 넣어주면 이와 같은 결과를 볼 수 있다.

authorization:https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/Authorization

http authorization: https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication

authortization값의 인코딩 방식에는 BasicBearer이 존재한다.
Bearer을 사용하면 토큰 값 앞에 Bearer 문자가 같이 붙어서 오기때문에 따로 분리하여 토큰값을 얻어야 한다.

Basic방식은 username과 password를 Base64인코딩 하는 방식인데 Base64는 별도의 키 없이도 복호화가 가능하기 때문에 보안상 좋지 않다고 한다.

Bearer에서 사용하는 OAuth 2.0 방식의 인증은 인증정보를 다른 웹서비스에 전달이 가능해 확장성이 매우 높다. (API를 다른 서비스에 이용하거나 OPEN API를 이용할 때 유용하게 사용할 수 있을 것 같다.)​

동아리 회원 인증

동그라미 서비스에서는 동아리별 회원인증 기능이 필요한데 JWT를 이용해 간단하게 구현할 수 있었다. payload 에 가입된 동아리 정보를 넣어 해당
동아리 원이 맞는지 인증하는 방식
으로 구현했으며 로그인 인증 미들웨어와 마찬가지로 동아리원 인증이 필요한 API 요청에 대하여 미들웨어로 해당 로직을 추가해줬다.

--

--