Session 방식
세션은
클라이언트가 로그인을 위해 인증 정보를 서버에 전송
서버는 메모리에 사용자를 저장하고, 세션 아이디를 쿠키로 전달
클라이언트는 쿠키에 저장된 세션 아이디를 이용하여 요청함
서버는 일치하는 세션 아이디를 메모리에서 검색한 후 응답
Session 방식의 한계
웹 Application 서버 측에 저장한다는 것은 서버 메모리에 인증 정보를 저장한다는 것이다.
세션은 사용자의 인증 정보를 서버에 저장하며, 서버의 과부하를 유발한다.
특히 동시 사용자가 많아질수록 서버 메모리를 비례하여 사용하게 된다.
이러한 세션 방식의 한계를 보완하기 위해 아래의 방법들이 있다.
1. 인증 서버의 메모리 증설
- 메모리 부족을 보완하기 위해서 메모리를 늘리는 것이다.
- 물리적으로 서버 컴퓨터의 RAM을 업그레이드 시켜서 해결하는 방법이지만, 해당 방법은 물리적으로 성능을 높이는 데에는 한계가 있고, 사용자가 더 많아질수록 한계가 명확하다.
2. 인증 서버의 수 증가
- 인증 서버를 분산시켜 여러대를 사용하는 방식이다.
- 즉 분산 서버를 운영하는 것
- 하나의 서버를 노드라고 부르며, 어떤 노드에서 장애가 발생하더라도 다른 노드에서 서비스 제공이 가능.
- 사용자의 수에 따라서 서버를 증설하거나 감소시키는 확장에 유연하다.
2-1 > 로드밸런싱
클라이언트들이 서버가 여러대 일 때 어떤 서버에 요청해야하는지 결정하는 방법이 필요하다.
분산 서버 환경에서는 요청을 분산시켜주는 중개 매체인 로드 밸런서를 이용한 로드 밸런싱이 이루어짐
클라이언트는 로드 밸런서가 정해준 서버로 요청하게된다.
2-2 > 분산 서버 환경에서의 인증 정보의 공유
위의 그림처럼 분산 서버 환경에서의 세션이 공유되지 않는 stateful한 상태가 발생한다는 문제점이 있다.
1번 서버에서 인증을 받았을 때 , 1번 서버에서는 인가에 성공했으나 2번 서버에서는 인증 정보 세션이 존재하지 않아
인증에 실패하였다.
그래서 나온 아이디어가 서버 각각 세션에서 관리하던 인증 정보를 데이터베이스에서 관리하는 것이다.
서버는 이제 인증여부를 API 서버가 아닌 데이터베이스에 저장하며 , 다른 서버에서도 데이터베이스를 공유하여
인증 정보를 공유할 수 있게 됐다.
이제 서버 부하는 막을 수 있지만 데이터베이스의 부하를 고려해야한다.
2-3 > 데이터베이스 분산
데이터베이스의 부하를 고려하여, 데이터베이스 서버도 여러대 늘렸다.
그런데 해당 클라이언트의 인증 정보가 어느 데이터 베이스에 담겨있는지 알 수 없게됨.
이를 위해서 데이터베이스 샤딩이라는 개념을 도입
클라이언트 id별로 여러개의 데이터베이스에 분할하여 인증 정보를 저장하는 것.
그래서 클라이언트 요청에 담긴 유저ID 에 따라서 서버는 어떤 데이터베이스에 인증정보를 저장하고 조회할지 판단.
2-4 > 메모리 기반 데이터베이스 사용
데이터베이스를 분산시켜 과부화를 줄였지만
관계형 데이터베이스 사용에는 다음 사항들을 고려해야한다.
RDBMS를 사용하는 것은 비용이 크다.
인증 정보는 만료가 되어야하는데, 만료에 대한 데이터 처리를 별도로 해주어야한다.
따라서 인증 데이터의 저장은 Redis 와 같은 메모리 기반 데이터베이스의 사용을 고려할 수 있다.
-> 보조기억장치를 사용하지 않고 메모리를 사용하므로 속도가 매우 빠르며, 만료 기간을 설정할 수 있음
-> 인증 데이터는 일회성 데이터이고, 데이터의 변동이 거의 없기에 메모리 기반 데이터베이스를 사용하기 유리하다.
-> 즉, 인증 과정 시 필요한 정보는 RDBMS와 같은 데이터베이스를 사용하며,
인증 후 요청시마다 인가 과정은 메모리 기반 데이터베이스를 사용하면 성능 향상에 도움이 된다.
위의 세션 인증 방식의 단점들을 어느정도 해소 시켜주는 방식이
TOKEN 방식이다.
토큰 인증은 세션 인증 방식과 다르게 인증이 완료되었을 시 인증 정보를 서버에 저장하는 것이 아니고
클라이언트에 저장한다.
인증을 완료하면 서버는 인증완료 의미의 토큰을 클라이언트에 부여
클라이언트는 API 요청 시 토큰을 HTTP 헤더에 붙여서 보내게 되며 서버는 토큰을 바탕으로 인가처리를 함.
토큰은 암호화되어 클라이언트에 저장된다.
토큰은 일반적으로 유효시간을 설정 후 발급하여 기간이 지날 시 사용할 수 없게 된다.
JWT 토큰
- > json Web token 웹에서 토큰 인증 방식으로 많이 사용되는 토큰의 종류이다.
- > JSON으로 만들어진 인증 관련 정보를 인코딩한 토큰이다.
-> 토큰에 대한 정보 인증에 대한 서버측에 전달할 정보, 검증되었음을 증명하는 signature 를 포함
JWT 토큰의 단점과 보완
- Payload 부분은 단순히 base64형식으로 인코딩했한 수준이기 때문에 안의 데이터를 볼 수 있다. 따라서 민감한 데이터를 넣지 않는다.
- 이미 발급된 토큰에 대해서는 사용자의 인증과 인가 처리를 무효화하기 어렵다. 따라서 토큰이 탈취당하여 사용될 수 있다.
- 위의 문제를 극복하기 위해서 토큰 만료 시간을 짧게 주어 탈취당하여 사용되기 이전에 무효화시키는 방법을 사용한다.
- 그렇지만 토큰 만료 시간을 짧게 준다면 매번 다시 인증 과정을 거쳐야 하는 문제가 있다.
- 이를 위해 도입된 개념이 Access Token과 Refresh Token의 개념이다.
JWT Access /Refresh Token 인증 플로우
토큰 만료 시간을 짧게 주게 되면 다시 인증 과정을 거쳐 재발급을 받아야 한다.
그래서 다시 로그인같은 인증 과정을 거치는 것이 아니라, Refresh Token을 통해서 인증 과정을 대신하려고 한다.
평상시 API 인가에 사용되는 토큰이 Access Token이라면,
Refresh Token은 Access Token이 만료되었을 헤더에 포함시켜서 Access Token 재발급 요청을 하는 데에 사용된다.
보통 Access Token은 시간을 2~5분 내외같이 짧게 주는 반면 Refresh Token은 2주 정도로 길게 주는 편이다.
클라이언트 | 서버 | |
인증 | ||
1 | 로그인 요청 | |
2 | 데이터베이스에서 ID와 비밀번호 대조 후 일치여부 확인 | |
3 | 일치 시 암호화된 토큰 생성 | |
4 | 응답으로 Access 토큰 / Refresh 토큰을 반환 | |
5 | 클라이언트는 토큰을 저장 | |
인가 | ||
1 | API 요청 시 헤더에 Access Token을 포함시켜 요청 | |
2 | 토큰 유효성 검증 | |
3 | 유효성 확인 중 Access Token 만료가 되지 않음 | |
4 | 응답을 받음 | 검증 완료되었다면 API 로직 처리 후 응답 |
재발급 | ||
1 | API 요청 시 헤더에 Access Token을 포함시켜 요청 | |
2 | 토큰 유효성 검증 | |
3 | 유효성 확인 중 Access Token 만료됨 | |
4 | 응답으로 Access Token 만료가 되었음을 보냄 | |
5 | Refresh Token을 헤더에 포함시켜 Access Token 재발급 요청 | |
6 | Refresh Token의 유효성 검증 | |
7 | 새로운 Access Token을 응답으로 반환하여 발급 | |
8 | 새로운 Access Token 저장 |
인증
- 앞의 인증 플로우와 다른 점은 인증 완료 시 Access Token과 함께 Refresh Token을 발급한다.
인가와 토큰 재발급
- 인가 중 Access Token이 만료되었을 때 클라이언트에 만료되었음을 응답으로 보낸다.
- 클라이언트는 만료되었음을 확인하고 Refresh Token을 헤더에 실어서 Access Token의 재발급을 요청한다.
- 서버는 마찬가지로 Refresh Token의 유효성을 검증한 후, Access Token을 재발급한다.
- 재발급된 Access Token으로 API 요청을 한다.
https://velog.io/@jellyjw/JWT%EC%99%80-session
https://velog.io/@mieum/Session-vs-JWT
https://sjh9708.tistory.com/45
https://sjh9708.tistory.com/46
'STUDY' 카테고리의 다른 글
[라이브러리] react-spring 애니메이션 구현 (1) | 2024.09.29 |
---|---|
[라이브러리] react hook form 유효성 검사하는 폼 만들기 (2) | 2024.09.18 |
<E2E 테스트> playwright E2E 테스트 및 깃허브 CI 설정하기 (1) | 2024.09.14 |
[react-signature-canvas] 전자서명 구현하기 (1) | 2024.09.13 |
axios 인스턴스 (0) | 2024.09.10 |