[ Node.js ] 로그인 프로세스(JWT, 암호화, Hash)
in BackEnd
로그인 프로세스(JWT, 암호화, Hash)
로그인 역사
ID정보를 백엔드 서버에 많이 넘겨주다보니 부하가 많이 걸렸다.
해결방안으로 백엔드메모리를 늘려주는 방법으로 scale-up을 해줬는데
접속자가 늘어날수록 여전히 부하가 심했다.
그래서 해결방안2로 백엔드 컴퓨터를 복사했는데
이번에는 또 세션까지 scale out을 안해서 기존의 로그인 정보를 받는 stateful 상태의 백엔 아니면 로그인 정보가 없다는 문제가 있었음
그래서 stateless상태로 컴퓨터를 확장했다.
현재는 로그인정보를 DB에 저장하는데,
저장을 할때 수평 파티셔닝(=샤딩)으로 DB부하를 분산 시긴다.
- 그리고 메모리 기반의 session을 디스크 기반의 token으로 변경했고
- disk에 저장되어서 속도가 느렸던 단점을 메모리 기반의 Redis라는 메모리를저장하는 임시 DB에 저장하게 되었다(그치만 컴 종료하면 data날아감)
- scale-up : 메모리 향상
- Scale-out : 안정성을 높였다. but 지금은 불가능함. 트래픽 많아지면 컴퓨터만 사주면 됐다
- Stateful : 컴퓨터가 특정 상태를 가지고 있는것
- stateless : 컴퓨터가 특정 상태를 가지지 않는것
인증 vs 인가
인증(Authentication)
: 로그인 증표를 얻어오는 과정 => (로그아웃전까지) 1번만 실행한다
인가(Authorization)
: 로그인 증표를 던져 증명하기 => 수도없이 실행
암호화
기존에
{ loginId : U001, isLoggedIn: true}
이런 데이터를 암호화하면 'dfjkslfwe10dk87dfl'
이런식으로 암호화
가 된다.
'dfjkslfwe10dk87dfl'
을 다시 { loginId : U001, isLoggedIn: true}
이렇게 바꿔주는 작업을 복호화
라고 한다.
암호화와 복호화를 같이 할 수 있는 암호화를 양방향 암호화
라고 하고,
암호화만 가능한 암호화를 단방향 암호화(Hash)
라고 한다.
Hash란 ‘원본을 알아볼 수 없게 뭉개다’ 라는 뜻이 있다
해커들은 단방향 암호화여도 이 암호화를 풀기위해 공격하는 몇가지의 방법을 사용하는데,
그중에 가장 대표적인게
- 무차별 대입공격(bruteforce)
- rainbow table : 알고리즘에 대한 input output을 가지고 있는 table
이 있다.
그렇기에 이 해커들의 손에 들어가더라도 복호화할수없게 만들어주어야 하는데
현재까지 나온 방법으로는 가장 강력한게 salt
라는 방법이다.
근데 이름 진짜 귀여움.. salt가 뭐야 salt가… 소금치면 맛이 완전히 달라져서 이름이 이렇다고 한다…🤤 기여어…
이 salt를 사용하기 위해서는 라이브러리를 사용해야하는데
이 라이브러리는 bcrypt(비크립트)
라고 불린다.
yarn add bcrypt
yarn add --dev @types/bcrypt
이렇게 설정해주고
import * as bcrypt from 'bcrypt';
async createUser(password){
const hashedPassword = await bcrypt.hash(password, 10);
}
이렇게 사용하면 된다.
어떤 값을 받아서, 몇번의 해싱을 해줄건지 결정한다. 2번째 인자값이 몇번의 해싱을 해줄건지 정해준다.
10번이 디폴트라고 한다.
이렇게 10번(round)를 돌리면 1234를 입력해도 $2b$10$SuHcKRk7wkQur3JgelQtReI8kvkNRsATNq4X47QD3yvoy0HlgYZ.S
이런식으로 해싱된다.
JWT (Json Web Token) : 웹에서 사용하는 Json 형태의 토큰
비밀번호 없이고 열람이 가능하기 때문에 중요내용은 올리면 안된다.
아까 위에서 작성한 로그인 역사를 보면 순서는 이렇다.
1. session 방식 사용
2. scale-out 확장문제
3. DB샤딩으로 병목해결
4. redis로 DISK I/O 해결
5. JWT로 Redis 대신하기