본문 바로가기
리액트 공부와 함께 하는 일상/5주차

[TIL] 1. 로그인의 역사

by fefe94 2022. 2. 14.

 

로그인의 필요성

 

브라우저, 프런트, 백엔드, 디비가 있습니다.

(각각 포트가 필요해서 서버라고 부릅니다.)

 

브라우저 주소창에 주소를 입력하고 엔터를 누르면

프런트에서 html, css, js 같이 하드 코딩한 정적 데이터들을 받아 옵니다.

 

그 후에 필요한 데이터를 useQuery를 통해 디비에서 꺼내옵니다.

(api로 요청하면 게시물을 받아오는 식입니다.)

 

이때 api 요청들 중에 로그인이 필요한 요청들이 있습니다.

createPayment

updateProfile

처럼 결제를 하거나 프로필 수정을 하는 부분에서는

백엔드에서 누구 것을 업데이트 하겠다는 건지 알아야 합니다.

 

백엔드와 브라우저 사이에 뭔가를 알고 있어야 하는 부분.

로그인의 필요성이 여기서 나오게 되었습니다.

 

 

 

로그인 옛날 방식

Session: 백엔드 메모리에 로그인 정보 저장하기

브라우저에서 백엔드로 email/pw 를 입력하여 로그인 합니다.

(백엔드에 email/pw 받는 로그인 api가 있을 것입니다.)

 

데이터 베이스의 User 테이블에

철수 / a@a.com / 1234 이런 것이 있습니다.

백엔드에서는 해당 계정을 데이터 베이스에서 찾아보고 

백엔드 컴퓨터 메모리(Session - 변수에 저장하듯이 백엔드 메모리에 저장했다고 보면 됩니다.)

에 '철수 로그인함' 이라고 저장합니다.

 

디스크 - 데이터 안 날아감. 느리다.

메모리 - 컴퓨터 껐다 켜면 데이터 날아감. 빠르다.

 

어쨌든 이런식으로 예전에는

백엔드의 변수에 철수가 로그인했다고 기록을 해놨었습니다.

이 기록에 대한 이상한 아이디 를 만들어서

이것을 브라우저로 돌려 줬습니다.

 

그다음부터는 철수가 api를 요청하면

이상한 아이디 를 같이 브라우저로 보내줍니다.

 

createPayment를 하면

백엔드에서는 누가 결제했는지 알아야 하는데

알 방법이 없으니 브라우저에서는 백엔드한테

받았던 이상한 아이디 를 보내줍니다.

그러면 백엔드는 그게 철수인걸 알아서

철수니까 결제 되게 해줘야 겠다! 라고 합니다.

이걸 인증이라고 합니다.

 

이상한 아이디 같은 정보가 있어야 

인증이 되는 것입니다.

 

(여기서는 메모리 세션에 저장했는 것이 핵심입니다.)

 

그런데 문제가 발생합니다.

백엔드 컴퓨터에 갑자기 너무 많은 사람들이 들어오게 됩니다.

백엔드 컴퓨터에 사용자가 몰려

여러 명의 브라우저가 생기면

백엔드에서는 이걸 한번에 다 처리를 못합니다.

 

scale up

그래서 CPU메모리넉넉하게 늘려주는데

이를 scale up 이라고 합니다.

 

scale out

백엔드 컴퓨터를 똑같이

복사 붙여넣기 복사 붙여넣기 식으로

늘려줍니다.

똑같은 백엔드 컴퓨터니까 여러 백엔드에게

브라우저 요청을 받게 된다.

이런 식의 확장을 scale out 이라고 합니다.

 

수평적으로 확장한 것으로 똑같은 백엔드를

복붙복붙한 방식입니다.

어차피 안의 api는 똑같기 때문에

여러개의 yarn dev 여러개의 서버를 사용할 수 있습니다.

 

그런데 여기서 또 문제가 발생합니다.

 

Stateful : 백엔드가 각각 자기만의 상태를 가지고 있는 것

 

 

철수 로그인 정보가 가운데 백엔드 컴퓨터에

저장되어 있어 다른 백엔드에서는 처리가 안됩니다.

 

다른 백엔드에서 처리가 안되고 있는 이상태를

stateful(백엔드가 각각 자기만의 상태를 가지고 있는것.)하다고 합니다.

 

백엔드에서 상태를 가지고 있다면

scaleout. 수평적 확장을 할 수 없습니다.

 

 

DB에 로그인 정보 저장하기

 

그래서 그다음 방법으로

db에 로그인 정보 저장하기 방식을 사용하여

dlfjgrp scale out이 가능하게 됩니다.

 

백엔드는 이렇게 stateless가 되었습니다.

세션에 저장하던 로그인 정보를 디비에 넣게 됨.

 

이렇게 백엔드는 충부닣 여러 명이 동시 접속해서 처리를 할 수 있게 되었습니다.

그런데

그러면 디비에 접속하는 양이 많아지는거 아닌가 싶습니다.

 

그럼 디비도 나눠주면 되지 않을까요?

백엔드가 n개면 디비도 n개.. 이런식으로 만들어주면 어떨까 싶지만

디비는 나눌 수가 없습니다.

 

디비도 어디든 접속해도 상관없게끔 해주려면

똑같이 10테라 바이트 식으로 용량이 커야 합니다.

이 방법은 비용이 많이 드므로 별로 효율적인 방법은 아닙니다.

 

그래서 디비를 쪼갭니다.

 

파티셔닝 : 인증 테이블 쪼개기

 

 

table이 있으면 수직으로, 수평으로 자릅니다.

이를 수직 파티셔닝, 수평 파티셔닝 (데이터베이스 샤닝) 이라고 하며

이라고 합니다.

 

로그인 현재 방식

인증 테이블을 3개로 쪼개어 주었습니다.

 

브라우저, 백엔드, 디비가 있습니다.

여기서 디비를 세개로 나눕니다.

1-100: 철수 로그인 함

101-200: 영희 로그인 함

201-300: ...가 로그인 함

이런식으로

백엔드 컴퓨터를 무수히 확장 가능해집니다.

 

이때, Disk에 저장된 것을 거져오는 것(DB를 긁는다고 표현)이

속도가 느리기 때문에 디비 앞에 Redis를 두고 여기에 로그인 정보를 저장합니다.

Redis는 메모리에 저장하는 거라 굉장히 빨라집니다.

 

이게 현재 방식입니다.

 

이제부터 위에서 말한 이상한 아이디를 토큰이라고 하겠습니다.

철수 만의 고유한 인증서인 토큰을 발급합니다.

그래서 저 토큰을 브라우저에게 돌려줍니다.

브라우저는 state에 저 토큰을 저장합니다.

 

그밖에 브라우저에서 저장할 수 있는

저장 공간은 cookie, localStorage, sessionStorage 등이 있습니다.

 

브라우저에서 createPayment할 때 토큰도 같이 백엔드로 보내준다.

백엔드에서는 redis를 뒤져서 해당 토큰으로 철수임을 알고

creatPayment되게 해줍니다.

 

토큰을 발급해서 redis랑 사용하게 한다. (DB없이 사용하고 싶다.)

 

디비에 저장 안하고 디비 없이도

할 수 있으면 좋겠다는 생각을 합니다.

 

토큰을 발급해서 redis랑 사용하게 하는 것인데요.

 

먼저, 유저 정보 같이

중요한 데이터를 암호화하고자 합니다.

암호를 푸는 것이 복호화입니다.

 

 

이제 암호화 필요 없이도 해보려 합니다.

 

백엔드에서 철수 관련된 객체를 만듭니다.

토큰 키를 만들어서 브라우저에게 줍니다.

브라우저 측에서 state에 토큰을 저장해두고 있습니다.

 

 

createPayment 할 때

맹구가 받은 토큰을 백엔드로 넘겨줍니다.

 

백엔드 자체에서 저 토큰을 복호화 해버립니다.

복호화해봤더니 객체가 있고 그 안에

name, id, 로그인 만료 시간

이 있었습니다.

그러면...

로그인이 지금 성공된것입니다.

 

아직 내일이 안됐기 때문에 유효한것입니다.

(만료시간은 내일까지.)

이사람이 어떤 컴퓨터 어떤 백엔드에서 접속한건지 모르지만

암호화 열쇠는 백엔드에만 있습니다.

검증했을 때 검증이 완료 된것입니다.

즉 로그인이 완료가 됩니다.

 

그래서 디비를 열지 않고도 백엔드 자체가 디비가 된것입니다.

시간이 안지났다는 것은 로그인을 방금 전 했다는 것입니다.

시간이 지났다면 토큰 거절 했을 것입니다.

디비 없이 샤딩 없이

복잡한 과정 없이 로그인 처리가 가능하게 된것입니다.

 

 

JWT 토큰: Json Web Token

이 때 이 토큰이 jwt 토큰입니다.

Json Web Token 자바스크립트 오브젝트 노테이션

JS- 객체 처럼 표기했다는 것

즉, 객체처럼 표기한 토큰, 제이슨 토큰이라고 합니다.

 

 

 

댓글