1. JWT(JSON Web Token)란?
- 서명 검증을 통해 토큰의 위변조 유무를 확인할 수 있도록 사용하는 JSON 기반의 토큰
- 서명이 검증되어 payload가 위변조되지 않았다는 것이 확인되면 payload 정보를 신뢰하여 사용한다.
💡 토큰이 발급되면 누군가가 함부러 변경하지 못하게 서명을 사용한다.
2. JWT의 구조
- JWT는 . 을 기준으로 header(헤더) / payload(내용) / signature(서명) 으로 이루어져 있다.
- 누군가가 payload을 변경하려고 하면 서명도 같이 변경해 줘야한다.
💡JWT 어떻게 구성되는지는 알았는데 실제 작동은 어떻게 할까?
HMAC(Hash based Message Authentication Code)
- 송신자와 수신자는 공통 비밀키(secret key)를 하나 씩 가지고 있다.
- hash 값을 구해서 공통 비밀키를 암호화 하는데 이것을 서명 생성이라고 한다.
- 이때 서명은 데이터와 비밀키 둘 중 하나만 바껴도 바뀐다.
- 송신자가 데이터를 수신자(네트워크)로 보낼 때 데이터+서명을 같이보낸다.
- 수신자(네트워크)는 받은 데이터와 서명을 분리함 → 사전서명
- 분리한 데이터를 자신이 가지고 있던 공통 비밀키와 결합해 다시 새로운 서명을 만들어 냄 → 사후서명
- 사전 서명과 사후 서명을 비교한다.
- 이런식으로 네트워크는 데이터가 위변조되지 않았다는 걸 확인함 → 무결성 검사
3. JWT 의 검사 방식
JWT는 두가지의 검증 방식으로 payload의 위변조를 감시해서 잘못된 접근을 방지한다.
3.1 HS 방식
- HMAC-SHA
- secret을 이용해 서명생성, 검증 (비밀키 방식)
- 백엔드에서 가지고 있는 secret키가 있다.
- 예를들어 사용자가 로그인하고 서버에서 인증해서 사용자 확인까지 하면 JWT를 생성한다.
- 생성된 JWT을 응답하고 이렇게 받은 토큰을 브라우저는 저장소에 저장한다.
- 이때 브라우저 내부 저장소는 indexedDB / localStorage / HttpOnly Cookie 등이 있다.
- 이렇게 발급받은 토큰은 서버에 있는 리소스에 접근할 때 사용 된다.
- 서버는 토큰을 검증 후 접근을 허용한다. (위변조되지 않았는지)
💡 그럼 해커가 토큰을 똑같이 위조할수도 있는거 아닌가?
백엔드에서 가지고 있는 secret키를 모르기 때문에 그렇게 하기가 어려움
3.2 RS 방식
- RSA-SHA
- 서명생성은 Private Key, 서명 검증은 Public Key를 이용함 (public key + private key = key pair)
- 서명 생성과 서명 검증이 나누어질 뿐 응답하고 받은 토큰으로 접근하는건 HS와 같다.
4. 클라이언트에서 구현해야 할 기능
- 백엔드와 통신을 위해 로그인 후 받아온 JWT 토큰을 브라우저 내부 저장소에 저장한다.
- 대표적인 세가지 저장소
- IndexedDB
- LocalStorage
- HttpOnly Cookie
- 인증된 사용자만을 위한 리소스 API에 접근할 때 Authorization 요청 헤더를 이용해 Bearer 토큰으로 전달한다.
💡이때, 프론트엔드에서 해야할 것은?
- 저장된 JWT에 접근하는 코드를 만들어야 한다.
- 앱 내부에서 접근 제어를 해야 한다.
- 즉, 로그인하지 않고 리소스에 접근하면 로그인 화면으로 이동시켜야 한다.(react-router를 이용)
5. WebStorage
localStorage | sessionStorage | IndexedDB |
key-value 형식의 텍스트 | key-value 형식의 텍스트 | 객체 타입을 저장 |
브라우저 종료 후 재시작해도 정보 ⭕ | 브라우저가 종료되면 사라짐 | 비동기 방식 |
다른 창, 탭을 통해서도 접근 ⭕ | 다른 탭, 창에서 접근 ❌ | |
동기방식 | 동기방식 |
6. 세가지 저장방식의 단점
WebStorage | Httponly Cookie | Google Firebase |
자바스크립트 코드로 접근하기 때문에 XSS 공격의 위험이 존재 | 자바스크립트 코드로 쿠키를 열람할 수 없기 때문에 XSS 공격에 대해 상대적으로 안전 | IndexedDB 사용 |
자동 네트워크 전송을 지원하지 않기 때문에 클라이언트 애플리케이션이 직접 전송 | HTTPS를 반드시 사용해야 하고 domain, sameSite와 같은 설정이 번거롭고 테스트가 힘듬 | XSS 공격에 대한 방어를 철저히 하는 것이 가장 중요함 |
XSS 취약점을 노려서 외부 API를 호출하는 방법으로 XSS 공격이 가능 |
💡그럼 대체 토큰은 어떤 저장소에 저장해야할까?
- refresh_token은 HttpOnly Secure Cookie 혹은 localStorage, IndexedDB
- access_token은 유효시간을 짧게 하여 localStorage, IndexedDB, 브라우저 메모리 중 한 곳에 저장
이때, XSS 공격을 방어할 수 있는 처리가 필수인데 리액트는 리액트는 상대적으로 XSS로 부터 안전하다. 따라서 localStorage를 사용해도 무방하다.
7. protected route란?
- react-router를 이용해 권한이 있어야만 접근할 수 있는 Route
- ProtectedRoute의 구성을 잘 이해하고 있는것이 중요하다.
📌
원형섭 강사님 실시간 강의
'Front-end > etc' 카테고리의 다른 글
유튜브(Youtube) API - Key 발급받기, 사용하기 (0) | 2024.03.14 |
---|---|
프리텐다드(Pretendard) 폰트 적용하기 (0) | 2024.03.05 |
프로젝트 vercel로 배포하기 (환경변수 에러 해결하기) (1) | 2024.01.10 |
.env 파일로 환경 변수 설정하기 (0) | 2024.01.09 |
리액트 프로젝트 firebase로 배포하기 (프로젝트 생성, 호스팅 설정, 배포) (0) | 2023.03.17 |