로그인 기능이 요즘 어떤게 트렌드인지, 어떻게 하면 보안을 강화할 수 있는지 생각해야함!
인증(Authentication) - 한번만!
인가(Authorization) - 내가 로그인됐다는 걸 필요로 하는 API 요청할 때마다 한다. (결제목록 보기, 등등)
접속자가 많다는 것은 메모리가 많이 필요하다는 의미!
stateful(상태를 가지고 있는) 상태에서는 쉽게 scale-out이 되지 않는다! stateless 상태에서 가능!
stateless => 상태가 없는 상태
session으로 다 쏠려서 느려지는 병목현상이 일어난다!
병목현상(bottle neck): 병의 목부분에 쏠려서 느려지는 현상
수직 파티셔닝과 수평 파티셔닝이 있다. 수평 파티셔닝을 샤딩이라고 부르기도 한다. 샤딩을 사용하면 병목현상을 해결할 수 있다!
트래픽을 이렇게 분산시킬 수 있다.
하지만 여기서 속도가 문제될 수 있다.
인가를 할때마다 api 요청 하고 그때마다 로그인 되어있는지 세션테이블에서 확인해야하는데,데이터베이스에 데이터를 저장한다는 것은 디스크에 저장한다는 의미인데,
DISK Input/Output(Disk I/O) 이 발생한다는 의미이다. 이는 곧 속도저하를 의미한다.
하지만 Redis를 사용하면 메모리에 저장이 된다. 껐다 키면 사라진다는 단점이 있지만 성능은 몇십배 이상 빨라서 db보다 빠르게 조회가 된다. 따라서 접속자가 많아지면 무조건 사용해야 한다!
브라우저가 있고 백엔드가 있다. 백엔드 api에 login과 fetchUser가 있다. 그리고 db가 있다.
백엔드에 이메일과 비번 요청을 한다. (회원가입은 이미 되어있는 상태여야함)
원래는 Redis에 저장되어있는거 확인, 하지만 새 방법은 변수로 객체를 만들어버린다. 그리고 이걸 암호화를 시킨다. 이때 이 객체를 Json Web Token(JWT토큰) 이라고 한다. 그러면 알 수 없는 값으로 변환된다. 그리고 그것을 로그인 증표형태로 브라우저 저장소로 보낸다. 그리고 인가할 때 마다 그 암호화된 로그인 증표를 보내서 복호화(암호를 푸는 것) 를 한다. 그래서 Redis에서 한번 더 요청할 필요없이
바로 db에서 정보를 꺼내줄 수 있다.
하지만 더 깊은 보안을 원할 때는 이 방법에 Redis를 추가하기도 한다.
실습할 것:
1. 회원가입
2. 증표 받아오기(인증)
3. 증표를 사용해서 내 정보 요청해보기(인가)
4. 내 정보 정상적으로 받아오기
우리는 실습에서 JWT 토큰을 accessToken 용도로 사용한다!
JWT 토큰 특징:
https://jwt.io/ 사이트를 이용하면 decoded(복호화된) 데이터를 확인할 수 있다.
세션스토리지 => 브라우저 껐다키면 사라짐(새로고침은 유지)
로컬스토리지 => 껐다 켜도 남아있음
쿠키 => 백엔드와 브라우저가 간에 데이터를 주고받는 연결공간
위 세 가지는 브라우저 저장소라고 함!
변수 => 새로고침만 해도 사라짐
양방향 암호화: 암호화도 되고 복호화도 됨 - 별로 안전하지 않다.
단방향 암호화(hash): 암호화는 되는데 복호화는 안됨(복호화가 안되는 알고리즘)
하지만 해싱을 해도
레인보우 테이블, 무차별 대입공격(Brute Force Attack)에 의해 해킹당할 수 있다.
따라서 암호에 salt(나만의 문자)를 붙여서 그것을 암호화하고 그 결과를 다시 hash함!(hash 반복)
이 방식을 키 스트레칭 이라고 한다!