팀프로젝트로 스터디 사이트를 만들어 보기로 했다. 아직 1인분도 못 하는 무지의 인간이지만(;-;) 이해라도 하기 위해 모르는 개념을 일단 정리하려고 한다. 먼저, 사이트를 이용하기 위한 로그인, 회원가입부터 구현을 시작했다. ID/Password 값을 받아서 데이터베이스와 비교하는 것이 아니라 JWT(Json Web Token)을 이용한다고 한다. (Json은 뭐고 JWT는 뭐죠....)
JWT
1) Why JWT?
HTTP 통신
JWT를 왜 사용하는가가 나와야하는데 갑자기 HTTP 통신이 등장했다. "로그인"이라는 과정은 서버와 클라이언트가 데이터를 주고 받는 통신 방법이 필요하다. 그 통신 방법이 HTTP라는 프로토콜(통신 방법)이다. HTTP는 아래와 같은 특성을 가진다.
- connectionless
HTTP는 연결을 유지하지 않는다 라는 특성이 있다.
HTTP 통신은 응답 후 연결이 끊기게 되며 과거에 대한 정보를 전혀 담지 않는다.
- stateless
HTTP는 상태를 유지하지 않는다 라는 특성이 있다.
서버와 클라이언트는 첫 번재 통신을 하고 나서 두 번째 통신을 할 때는 이전의 통신에 대한 정보를 가지고 있지 않기 때문에 새롭게 갱신해줘야한다.
즉, 위 특성들 때문에 "로그인"을 구현할 때 어려움이 있다. 사용자가 매번 서버에 요청을 보낼 때마다
자신이 누구인지 계속해서 인증을 해주어야 한다는 것!! (because 연결 유지 X & 상태 유지 X)
매번 서버에 사용자가 누구인지 인증을 하는 과정은 번거롭고 매번 요청을 보내야 하기 때문에 웹페이지가 느려지는 원인이 된다.
so, 로그인을 처리하는 방법
- Bad
유저에게 ID/Password를 받아서, 서버의 데이터베이스와 그냥 비교하는 방법이 있다.
해당 방법은 로그인 유지가 안 될 뿐더러 정보가 유지되지 않으면, 매번 페이지를 이동할 때마다 로그인을 다시 하거나, 상품을 선택했는데 구매 페이지에서 선택한 상품의 정보가 없거나 하는 등의 일이 발생할 수 있다.
- Good
Session(세션) vs Token(토큰)
사용자의 로그인 정보에 대한 것을 어디다가 유지, 저장을 하느냐에 따라 두 방식으로 나뉜다.
세션 방식 (서버 유지)
세션 방식은 서버의 메모리, 데이터베이스와 같은 서버의 자원들을 사용해셔 사용자의 정보를 유지시키는 방식이다.
토큰 방식보다 보안에 강하다는 장점이 있지만, 단점으로는 서버의 확장성이 떨어지고, 서버의 자원(세션을 저장, 유지할 공간)이 많이 필요하다. 또한 세션이 서버에 저장되고, 트래픽 분산을 위해서 여러 대의 서버를 사용할 때 만약 사용자가 로그인을 했을 때는 만들어진 세션을 참조해야 하기 때문에 처음 로그인한 그 서버에서만 요청을 보내야 한다는 단점이 있다.
토큰 방식 (클라이언트 유지)
토큰 방식은 사용자가 로그인을 하면 서버에서 발행해주는 토큰을 가지고 브라우저의 저장소에 토큰을 유지시키는 방법이다. 여기서 말하는 토큰은 바로 JWT이다!!
서버에 저장하지 않아서 서버에 확장성이 있고,
로그인을 했을 때 해당 서버에만 요청을 보내는 것이 아닌 요청이 들어왔을 때 해당 토큰이 유효한지만 체크하면 되기 때문에 어떤 서버로 요청을 보내도 상관이 없다!
2) What is JWT?
Json Web Token의 약자로,
JSON 객체를 사용하여 가볍고 자가수용적인 (self-contained) 방식으로 정보를 안전성 있게 전달해주기 위한 토큰이다. 전자 서명 된 URL-safe(URL로 이용할 수 있는 문자만 구성된)의 JSON이다.
JWT는 세 파트로 나눠지며, 헤더(HEADER), 페이로드(PAYLOAD), 서명(SIGNATURE)로 구성되며 세 부분을 점(.)으로 구분하는 구조이다.
JWT 사용과정
1. 브라우저의 로그인 과정에서 회원정보를 입력한다. (ID, PASSWORD)
2. 서버는 JWT를 만든다.
3. 서버는 브라우저에게 JWT를 보낸다.
4. 브라우저는 JWT를 가지고 서버에게 데이터를 요청한다.
5. 서버는 서명을 확인하고 유저 정보를 클라이언트에게 제공한다.
JWT 사용목적
- 회원 인증
JWT를 사용하는 가장 흔한 시나리오이다. 사용자가 로그인을 하면, 서버는 사용자의 정보를 기반으로 한 토큰을 발급하는 기능을 한다. 그 후, 사용자가 서버에 요청을 할 때마다 JWT를 포함하여 전달한다. 서버는 클라이언트에서 요청을 받을 때 마다, 해당 토큰이 유효하고 인증됐는지 검증을 하고, 사용자가 요청한 작업에 권한이 있는지 확인하여 작업을 처리한다.
=> 서버에서는 사용자에 대한 세션을 유지할 필요가 없다. 즉, 사용자가 로그인 되어 있는지 안 되어있는지 신경 쓸 필요가 없고, 사용자가 요청을 했을 때 토큰만 확인하면 되므로 세션 관리가 필요없어서 서버 자원과 비용을 절감할 수 있다.
- 정보 교류
JWT는 두 개체 사이에서 안정성있게 정보를 교환하기에 좋은 방법이다. 정보가 서명 되어있기 때문에 정보를 보낸 이가 바뀌진 않았는지, 또 정보가 도중에 조작되지는 않았는지 검증할 수 있기 때문이다.
3) JWT 프로세스
여기에 대해서는 아직 이해가 필요할 것 같다....................ㅎ
- 필요한 API
- Refresh API
- 새로고침, AccessToken 만료시에 호출 (setTimeout으로 자동 호출 설정 가능)
- RefreshToken을 쿠키에서 읽어와서 서버로 보냄
- RefreshToken,AccessToken을 다 받아올지 AccessToken만 받아올지는 선택
- Login API
- 로그인 시 호출
- RefreshToken,AccessToken 을 받아옴
- API 호출 후
- AccessToken는 header에 default로 설정하여 API마다 보내도록 설정
- AccessToken의 유효기간이 끝나기 전 자동으로 Refresh API가 호출되도록 설정 가능 (선택적)
- RefreshToken는 쿠키에 저장
- RefreshToken 또한 기간이 만료되면 재로그인이 필요!
- Refresh API
[참고]
'알아두면쓸데있는신기한잡학사전 > 고군분투흔적들' 카테고리의 다른 글
[Project] API, REST, REST API (0) | 2022.01.21 |
---|---|
[Project] 클라이언트와 서버 양 입장에서 로그인 과정 이해하기 (0) | 2022.01.20 |
[Design Pattern] 일반화 관계 (1) | 2021.04.14 |
[Design Pattern] 연관 관계 (0) | 2021.04.14 |
[Design Pattern] UML, 클래스, 관계 (0) | 2021.04.07 |