6월 20일

HSKwon·2022년 6월 20일
0
post-thumbnail

(난이도 있는 부분)

accessToken 복습
인증:토큰얻는과정
인가:게시글 등록, 상품등록 등 내가 철수임을 인정받는 과정

로그인을 하면 id/pw 넘김 => 그 데이터가 DB에 있는지 찾고 => DB에 있으면 백엔드 컴퓨터의 세션에 "철수:로그인함"과 같이 메모리세션에 저장, 세션id를 브라우저에 주게되면 브라우저에서 요청할때마다(ex.createUseditem) 세션id를 같이 보내게됨 // 만약 철수가 로그인이 되지 않아있다면 마켓등록을 못하고 에러메세지 던지게 설정 // 접속량이 1000명, 10000명 늘어나면 감당못하게됨 => 1. scale Up 과정을 통해 메모리 올렸음 // 2. 다른 컴퓨터에 똑같은 소스코드 설치해서 yarn dev(scaleOut)
BUT DB의 부하를 분산하지 못하였다.

    1. 수평 파티셔닝 : 샤딩
    1. 수직 파티셔닝

redis에도 저장하지 말고 JWT토큰에 저장해서 사용하자
{
name:"Chulsoo",
exp:~tomorrow
}
객체를 암호화, 복호화 (JWT) (JsonWebToken)

💡 최종적인 모습(accessToken -> ~JWT토큰)

  • 백엔드(부하 분산_scaleOut)
  • 로그인을 하면 메모리세션, db에 저장하는게 아니라 JWT토큰을 만들어서 저장
  • JWT토큰을 브라우저에 전달
  • state에 JWT토큰을 저장
  • JWT를 백엔드에서 복호화(객체를 복호화하면 얘가 철수이고, 내일까지 만료기간이구나!를 인식할 수 있음)
  • 만료시간이 넘었으면 에러메세지
  • 만료시간이 남았으면 createUseditem이므로 상품등록허용

    문제점 (중간에 accessToken탈취 가능성)

    만약 중간에 탈취당했다면 백엔드에서는 무조건 인가해줄 수 밖에 없음
    그래서 accessToken은 30분~2시간 사이만(탈취 당한다 하더라도 2시간 이내에 자동으로 무효화) (but 다시 로그인 해야만 하는 귀찮은 문제 발생)

💡 refreshToken

로그인해서 인증하면 jwt토큰을 만드는데, 1개를 더 만든다. 그래서 다른 jwt토큰의 용도는 refreshToken으로 사용할것임. jwt토큰1은 accessToken, jwt토큰2는 refreshToken(2주~2달)!

<인증과정>

  • document.cookie를 못하게 하는것(httpOnly, secure)
  • state(globalState, recoil)에는 accessToken, 쿠키에는 refreshToken
  • 백엔드에서 쿠키에 refreshToken을 넣어줬기 때문에 브라우저의 쿠키에 자동으로 refreshToken이 들어옴

<인가과정>


브라우저에서 상품명,가격,Bearer accessToken 등을 백엔드에 보냄(인가과정)

  • JWT(accessToken)를 복호화함
  • 복호화해서 통과를하면 상품등록

    복호화에 실패(사유:accessToken 사용 기한 만료)한다면 에러메세지 전달
    -> error: Unauthenticated
    -> apollo-setting 설정 (1️⃣onError로 gql에서 에러가 났을때 캐치하기)
    ->백엔드에 준비되어 있는 api(resotrAccessToken)를 이용하기
    -> 2️⃣토큰 재발급 : 리프레시 토큰을 보내고 정상이면 accessToken을 새로 발급받아서 브라우저로 보내준다
    3️⃣마지막 실패 쿼리 재시도
    1,2,3단계를 apollo-setting에 설정해줘야함
    🚀## accessToken 만료시간이 되었을때마다 이 작업이 한번씩 이뤄진다!!!(조용히 다시 로그인이 되었으므로 silent-auth라고 함)
    🚀apollo-setting을 https로 바꿔주기

- accessToken은 우리가 직접 넣어준것(Bearer ${accessToken})

- refreshToken은 자동으로 쿠키에 첨부됨!!!!(HTTP Only이기 때문에 document.cookie해도 토큰을 꺼내올 수 없음❌, 탈취 자체가 불가능함❌)

30-01 : 5초가 지나면 쿼리를 재요청할것임(accessToken이 만료된 상태, error를 띄우는게 아니라, error를 캐치 이후 accessToken을 재발급 받아서 페이지를 뒤로 이동해도 그대로 "철수님 환영합니다"를 띄울것임!!!)

하지만 문제가 있다 => 새로고침 하면 "철수님 환영합니다"가 사라짐!!

rest-api

/POST, /GET, ........
엔드 포인트가 너무 많아짐.... 하나로 통일시킬 수 없을까...? (포스트방식, 바디에 넣음)

단점

  • 내가 원하는것보다 조금밖에 못가져옴 (언더페칭 문제)
  • 내가 원하는건 fetchBoard 중에서도 title 하나인데 fetchBoard의 writer,title,contents... 등등 다 받아야함 (오버페칭 문제)

Graphql-api

  • 엔드포인트는 graphql 하나로만 하자
  • 포스트방식으로 바디에 함수를 넣자
  • 실행하고 싶은 함수 "목록"을 넣는 방식

    => graphql아 fetchBoards랑 createUseditem 두개 실행시켜줘

🤔 "조회" (fetchBoards)임에도 GET이 아니라 POST?

=>/graphql에 실행할 함수 목록을 적어주었고, 함수로 가서 실행을 해야 하므로 항상 POST로 쓴다.
=> 묶음으로 써서 보내기 때문에 어떤게 성공하고 어떤게 실패할 줄 모름! 그래서 일단은 성공처리를 한다(200을 띄움) (에러를 따로 따로 관리한다)
##💡 graphql은 사실 하나의 엔드포인트를 사용하는 포스트 방식의 rest-api다!!!

장점

  • 1.endPoint 단일화
  • 2.fetchBoard에서 title만 받아올 수 있음 (내가 원하는것만 골라 받을수있음_restapi의 오버페칭 문제를 해결)

사실 graphql이란건 없고 restapi를 변형한것이다

rest-api => react-query + recoil(미니리덕스)
graphql => apollo-client + recoil(미니리덕스)

profile
공부한 내용이나 관심 있는 정보를 글로 정리하며 익숙하게 만들고자 합니다.

0개의 댓글