[TIL] 22.11.30 - 로그인 기능

nana·2022년 11월 30일
0

TIL

목록 보기
38/50
post-thumbnail

로그인


기존 로그인 방식

📌 브라우저 저장 공간

  • 변수 : 새로고침 하면 데이터가 사라짐
  • 로컬 스토리지 : 브라우저를 껐다 켜도 남아있음 (새로고침시 유지)
  • 세션 스토리지 : 브라우저를 껐다 키면 사라짐 (새로고침시 유지)
  • 쿠키 : 저장기한, 보안강화 등 내장 -> 브라우저와 백엔드를 연결하는 역할. 쿠키에 데이터를 저장하면, 데이터가 브라우저와 백엔드 사이에서 자동으로 전달된다.
  • 브라우저에서 사용자가 이메일과 비밀번호를 입력해서 로그인하면, 백엔드를 통해 DB에 로그인 증표가 생성되고, 백엔드 세션에 저장된 로그인 증표를 브라우저로 다시 받아와 브라우저 저장공간에 저장한다.

=> 인증 (Authentication)


  • 로그인 시 브라우저 저장공간에 저장된 로그인 증표를 fetchUser API로 백엔드로 보낸다.
    백엔드 메모리 세션에 저장된 로그인 증표를 확인하고, DB에서 프로필 정보를 가져와 브라우저에 돌려준다.

=> 인가 (Authoriztion) 로그인이 필요한 API가 요청할 때마다 수행된다.


기존 로그인 방식의 단점

기존 로그인 방식은 메모리(RAM)에 저장되는 과정이라 컴퓨터가 종료되면 세션이 초기화되어 저장된 로그인 증표가 사라지게 된다.

또한 사용자 접속이 많아질 경우, 변수를 저장할 백엔드 메모리가 부족해지고 프로그램이 자동으로 종료된다. (서버가 터짐)

이를 해결하기 위해 scale-up / scale-out 방식이 나타났다.

  • scale-up : RAM 추가
  • scale-out : 백엔드 컴퓨터를 하나 더 사용해서 트래픽을 분산시킴

그러나 scale-up은 RAM 추가시 비용이 많이 들고, scale-out은 컴퓨터 분산시 메인 컴퓨터에만 Session이 저장되어 있는 상태(stateful)에서는 쉽지 않다는 단점이 있었다.

그래서 DB에 Session을 저장하게 되었다. (백엔드 Session은 stateless 상태)

그러나, DB에 있는 Session도 저장공간이 부족해진다. 병목현상 (bottle neck)에 걸린다.

병목현상을 해결하기 위해 테이블 분리 (파티셔닝)를 해주게 된다.

  • 수직 파티셔닝 : id email pass name / age school hobby
  • 수평 파티셔닝(샤딩) : user 1 ~ 1000 / 1001 ~ 2000

하지만 파티셔닝 또한 DB에 데이터를 저장 (DISK에 저장)하기 때문에, API를 요청해서 인가 할때마다 DB에 접속해서 데이터를 조회, 저장하게 되므로 DISK I/O 로 인해 속도가 느려진다.

이를 해결하기 위해 Session 정보를 Redis (메모리기반 DB) 에 저장해서 성능을 높여주었다. (대신 컴퓨터를 껐다가 키면 사라진다.)


최근 로그인 방식

최근 로그인 방식은 Redis에 로그인 증표를 저장하지 않아도 가능한 방법이다.

login API에서 로그인 데이터를 객체로 만들어서 암호화 를 시키고, 암호화 시킨 객체를 로그인 증표로 브라우저에 돌려준다. (인증)

인가를 받을때마다 암호화된 로그인 증표 브라우저에서 보내고, 백엔드에서 복호화(암호를 풀음) 해서 로그인 데이터 객체를 확인한다.

암호화와 복호화 과정을 통해 인증을 확인한 후, DB에서 프로필 정보를 꺼내서 받아올 수 있다.

로그인 증표를 토큰이라 한다.

📌 JWT토큰 (JSON Web Token)
JSON으로 만든 암호화된 로그인 데이터


양방향 암호화 / 단방향 암호화


  • 양방향 암호화

    비밀번호를 암호화 해서 다시 복호화 한다.
    복호화 알고리즘을 알아내면 보안 안정성이 떨어진다는 단점이 있다.

  • 단방향 암호화 (Hash 해시)

    암호화는 되는데 복호화는 불가능한 방법이다.
    다대일 관계로 복호화가 어렵기 때문에 보안이 높아진다.
    그러나, 해커가 레인보우 테이블에 암호 경우의 수를 입력해서 찾는 경우도 있다. (brute force attack 무차별 대입 공격)
    이를 해겨하기 위해 Hash시 salt 문자열(임의의 문자열)을 더해주고, 그 결과를 다시 Hash해주어(키 스트레칭) 무차별 대입 공격에 대응할 수 있다. (Hash 반복)



JWT 토큰 (로그인 증표)


회원가입 (createUser)
로그인(loginUser)
로그인인증(fetchUserLoggedIn)


JWT 토큰 특징

  • 누구든 복호화해서 볼 수 있다. (jwt.io 페이지)
    -> 중요한 내용(신용카드, 비밀번호 등) 사용x, 정말 필요한 정보만 사용해야 한다.

  • 조회는 할 수 있지만 조작은 불가능하다.

  • 인증 시 시그니처로 조작여부를 검증한다.

graphql에서 fetchIserLoggedIn 시 request header에 AccessToken을 보내주면 로그인 정보를 확인할 수 있다.


Recoil - 로그인 인증 증표 저장


accessToken 글로벌 스테이트를 만들어 준다.

ApolloSetting에서 uri 밑에 headers를 추가해준다.
Bearer는 백엔드에서 설정해 놓은 단어이다.

loginUser query로 accessToken을 받아온다.

loginUser 뮤테이션 시 return받은 accessToken값을 받아, global state에 저장해준다.

이때, accessToken이 없다면 로그인 실패 경고창을 띄워주고, 함수를 종료한다.

fetchUserLoggedIn 쿼리를 통해 로그인한 유저의 정보를 보여줄 수 있다.

profile
프론트엔드 개발자 도전기

0개의 댓글