JWT를 통한 로그인을 구현
JWT 토큰을 어디에 저장해야하는가?
기존 세션 로그인 방식에서 JWT 토큰을 이용한 로그인으로 변경하는 테스크를 진행하면서, 프론트에서 토큰을 어디에서 관리해야하는지에 대해서 정해야 했었다.
대게 프론트에서는 쿠키 / 로컬 스토리지 둘 중 하나로 나뉘는 것 같았다.
가장 대표적인 특징으로는
로컬 스토리지
- CSRF 공격에 상대적으로 안전함
- XSS 공격에 취약함
쿠키
- XSS 공격에 상대적으로 안전함 (완전히 안전하지는 않음)
- CSRF 공격에 상대적으로 취약함
- expire 설정 가능 (로그인 시간을 핸들링해야할 때 유리)
XSS
- Cross Site Scripting
- 공격자가 의도하는 악의적인 js코드를 피해자의 웹 브라우저에서 실행시키는 것
CSRF
- Cross Site Request Forgery
- 정상적인 request를 가로채 피해자의 요청으로 위조된 request를 보내 악의적인 동작을 실행시키는 것
선택?
Local Storage
- 먼저, 쿠키를 사용하여 토큰 작업을 진행한다면, 백엔드에서 추가로 쿠키를 위한 설정을 추가해줘야 한다고 함 ... 가장 큰 이유로 local storage 를 사용하게 된 계기가 된 것 같음
- 토큰의 expire 설정이 필요가 없었음
- 쿠키를 사용한다고 해도 XSS에 완전히 안전하지는 않기 때문
- 보안상의 이슈가 있지만 사내망 내에서 사용되는 서비스기 때문에 크게 신경을 안써도 되었던 것 같기도 함 (추측)
구현 (Vue 기준)
- 처음에는 router의
beforeEach
에서 Local Storage의 토큰 유무를 보고 리다이렉트 시키도록 구현하였다.
- 문제는 만약 토큰이 만료가 되거나 없는 상태에서 url 이동 없이 api를 호출한다면?
- axios의 interceptors 사용하여 요청을 보내기 전에 한번에 관리하는 방식으로 변경하였다.
결국 로직의 흐름은
' 로그인 -> localStorage에 토큰 저장 -> api 요청시마다 interceptors를 통해 header의 localStorage에서 가져온 토큰 확인 -> (토큰이 올바르지 않다면 로컬스토리지를 비워주고 로그인화면으로 리다이렉트) -> 토큰이 올바르다면 사이트 내 작업 -> 로그아웃 시, local storage 토큰 삭제 및 login페이지 리다이렉트'
로 진행되게끔 구현하게 되었다.