안녕하세요.
이번 글은 그님스 서비스의 인증 방식과 앞으로 인증 방식 관련 개선할 수 있는 사항들에 대해 소개해 보려합니다.
목차
- 인증 / 인가?
- 인증 방식?
- 해결 방안
- 왜 Jwt 토큰을 사용 했는가?
- 앞으로 적용해 볼 수 있을 것들!
인증 / 인가?
- 인증이란 내가 누구인지 인증한다 라고 설명할 수 있습니다
어떤 웹 서비스를 이용한다고 가정할 때 이 웹은 사용자가 누구인지 모릅니다
그래서 로그인을 통해서 내가 누구인지 알려주고, 등록된 회원이면 '인증된 회원'
등록안 된 회원이면 '등록 안 된 회원' 등으로 구분 할 수 있습니다.
- 인가는 어떤 리소스에 대한 권한이라고 생각하시면 편하겠습니다.
예를 들어, 철수와 맹구라는 아이들이 있고
철수는 매일 비밀 '일기'를 쓰고 있다고 가정하겠습니다.
그리고 맹구는 이 '일기'를 보면 안 됩니다.
정확히는 철수의 비밀 '일기'이기 때문에 맹구는 보게하면 안 됩니다.
하지만 철수는 자신의 '일기' 이기 때문에 마음대로 쓰거나 읽을 수 있습니다.
이러한 예시처럼 사용자에게 어떤 리소스에 대한 권한을 주는 것을 인가라고 할 수 있습니다.
인증 방식?
- 우선 인증 방식이 왜 필요할까요?
우선 클라이언트와 서버는 데이터를 주고 받습니다.
만약 클라이언트에서 서버에 사용자의 닉네임을 요청하는 Api를 호출한다면
서버는 그 사용자가 누구인지를 알아야 닉네임을 찾아줄 수 있습니다. - 사용자를 어떻게 구분 할 수 있을까요?
저희는 평소에 네이버나, 카카오 등의 서비스를 이용하면서 알 수 있듯이 사용자가 로그인을
하게 되면 그 정보를 받아와서 사용자를 구분할 수 있게됩니다.
그런데 만약 닉네임을 요청하는게 아닌, 채팅을 쓰고, 프로필을 바꾸고, 그저 마이페이지를 보는 동의 어떠한
액션을 취할 때 마다 로그인을 하게 된다면 그것은 사용자 입장에서 매우 불편할 것이고 개발자 입장에서도
액션 때마다 정보를 검증하고, 사용자를 찾는 등의 비용이 계속 발생하게 되는 것입니다.
그래서 보통 로그인할 때 인증된 사용자라는 것을 확일할 수 있는 객체를 던져줍니다.
예를 들어 설명하면, 놀이공원에서 자유이용권을 샀다고 가정하겠습니다.
자유이용권을 살 때만 어떤 계산을 하고 자유이용권을 얻은 뒤에는 놀이기구를 탈 때마다 자유이용권만 보여주면
놀이기구를 이용할 수 있습니다.
이 비유에서 '자유이용권' == '토큰', '놀이기구' == '서비스'라고 이해하시면 편할 것 같습니다.
해결 방안
- Session
- Jwt 토큰 (선택)
왜 Jwt 토큰을 사용 했는가?
- 저희는 인증 방식을 크게 Session과 Jwt 토큰 둘 중에서 고민하였습니다.
그 중에서 Jwt 토큰을 선택한 이유는 Session과 다르게 저장소가 필요없이
토큰 만을 가지고 인증을 할 수 있다는 점에 크게 메리트를 느껴서 Jwt 토큰을 사용하게 되었습니다.
앞으로 적용해 볼 수 있을 것들!
- 리프레시 토큰 도입
먼저 저희는 처음 기획할 때 Jwt 토큰을 도입하면서 리프레시 토큰을 도입하는 것은 배제하였었습니다.
그 이유는 리프레시 토큰을 쓰기 위해서는 리프레시 토큰을 저장할 저장소가 필요하게 되고 그러면 애초에 Session을 대신해 Jwt 토큰을 선택한 이점이 사라지는 것이라고 생각했기 때문입니다.
그럼에도 도입을 선택한 이유는 Jwt 토큰의 문제인 탈취의 위험성 때문입니다.
토큰 자체가 인증을 해주기 때문에, 반대로 말하면 이 토큰을 탈취 당할 경우 해커가 사용자인척 할 수 있게됩니다.
그것을 방지하기 위해 리프레시 토큰을 도입하여 Jwt 토큰의 만료시간을 줄이는 방법을 사용할 수 있습니다.
물론 탈취 자체를 막는 방법은 아니지만, Jwt 토큰의 시간을 줄임으로써 탈취의 피해를 최소화 할 수 있습니다.
그리고 위와 같이 탈취의 위험 때문에 Jwt 토큰의 시간을 엄청 길게 못 주어서 사용자가 일정시간마다 계속 로그인을 해줘야한다는 불편성이 있었습니다. 이것을 리프레시 토큰을 도입함으로써 Jwt 토큰 자체의 시간은 줄지만 한번 로그인 했을 때, 로그인 상태를 오래 유지해 줄 수 있다는 장점이 있습니다.
또한, 만약 리프레시 토큰이 탈취당한다 해도 리프레시 토큰은 저장소에 저장이 되어있기 때문에 Jwt 토큰과 달리
즉각적으로 삭제시켜 줄 수 있습니다. - Session을 쓰지 않는 이유
그러면 Session을 쓰면 되지 왜 토큰을 쓰냐는 의문이 드실 수 있습니다.
세션은 서버에서 상태를 유지하기 때문에, 서버의 부하가 높아질 수 있다고 생각하였습니다.
또한, 세션은 Spring 톰캣 메모리에서 관리하기 때문에 단일 서버일 경우에는 크게 문제가 없지만, 후에 서버가 늘어날 경우 세션을 서버마다 공유를 해줘야하기 때문에 세션 클러스터링 등의 기술이 필요하고, 레디스 등의 저장소가 따로 필요할 수도 있는 등 확장성에 불편함이 있을 것이라 예상되어 세션대신 Jwt 토큰을 계속 선택하게 되었습니다. - 리프레시 토큰을 도입함으로써 리프레시 토큰의 저장소 등을 고려해 볼 수 있을 것 같습니다.
읽어 주셔서 감사합니다.
'BE 프로젝트 일대기' 카테고리의 다른 글
AOP로 API 시간 측정하기 (0) | 2023.04.01 |
---|---|
[Be] 비밀번호 재설정 (0) | 2023.03.13 |
[BE] 소셜 로그인 (0) | 2023.03.09 |
GNIMS - 유저검색하기 (1) | 2023.02.27 |
그님스 BE는 코드 리뷰를 합니다. 그런데 잘되고 있나요...? (0) | 2023.02.26 |