stateful / stateless
scaleup / scaleout
RoundRobin) 백엔드에 나누어진 데이터를 나누어진 백엔드를 돌면서 확인
최소연결(least connection)) 데이터가 제일 적은 백엔드에 데이터를 보내준다.
Partisioning,,, 데이터 베이스 나누기 수직파티셔닝/수평파티셔닝(샤딩)
데이터베이스도 분산 가능 데이터베이스에서는 데이터가 디스크에 저장되어 느리지만 영구저장된다.
Redis 메모리에 저장되는 데이터 (영구저장하게도 바꿀 수 있지만... 기본적으로는 비영구적인 데이터)
해시 방식은 데이터를 알수 없게 만든다 단방향암호화 패스워드 해싱!!
토큰에 사용자 정보 저장 -> JWT(JSON Web Token)
((JSON 자바스크립트 객체 표기법))
탈취가능성있어 만료시간을 짧게 준다 30분~2시간 정도
accessToken 1시간 이후 토큰만료로 사용이 안되는 부분은 refreshToken을 사용하여 토큰을 재발급 받아줄 수 있다.
ResourceService -> BoardService / UseditemService / BasketService 등 작은 단위로 나뉘어진다 (MicroService Architecture, MSA)
장애가 나면 모든 서비스가 중단되었으나 이렇게 나누게 되면 장애가 난 한 서비스만 중단되고 나머지는 서비스 이용이 가능하다는 장점이 있다.
AuthService에서 로그인 시 JWT를 2개 발급받아 하나는 accessToken, 하나는 refreshToken으로 사용한다.
브라우저에서 state형식으로 accessToken 저장, refreshToken은 쿠키에 저장
쿠키 옵션에서 httpOnly: true, secure: true
httponly는 JS 사용 불가
secure는 https에서만 작동
쿠키는 API 요청 시 자동으로 따라 붙는 특징이있다
header에 accessToken, data를 넣어 백엔드에 요청, 데이터를 받아온다.
error: UNAUTHENTICATED로 에러 캐치, 해당하는 authService에서 refreshToken을 주고 accessToken을 새로 받아오는 API를 요청하며 accesstoken이 유효한지 검증한 후 유효하지 않다면 새로운 accesstoken을 돌려보내준다. 받은 accesstoken으로 실패했던 요청을 재시도한다.
refreshToken 하는 법
const errorLink = onError(({ graphQLErrors, operation, forward }) => {
if (graphQLErrors) {
for (const err of graphQLErrors) {
// 토큰 만료 에러 시
if (err.extensions.code === "UNAUTHENTICATED") {
// restore token
// const newAccessToken = getAccessToken(setMyAccessToken);
// 재요청
operation.setContext({
headers: {
...operation.getContext().headers,
authorization: `Bearer ${getAccessToken(setMyAccessToken)}`,
},
});
return forward(operation);
}
}
}
});
import { GraphQLClient } from "graphql-request";
import { gql } from "@apollo/client";
import { Dispatch, SetStateAction } from "react";
const RESTORE_TOKEN = gql`
mutation restoreAccessToken {
restoreAccessToken {
accessToken
}
}
`;
export const getAccessToken = async (
setMyAccessToken: Dispatch<SetStateAction<string>>
) => {
try {
const graphQLClient = new GraphQLClient(
"https://backend04.codebootcamp.co.kr/graphql",
{
credentials: "include",
}
);
const result = await graphQLClient.request(RESTORE_TOKEN);
const newAccessToken = result.restoreAccessToken.accessToken;
setMyAccessToken(newAccessToken);
return newAccessToken;
} catch (error) {
console.log(error.message);
}
};
주의할 점!!!
항상 brower render 전에 error를 먼저 잡아줘야하니까 error 부분은 항상 먼저 써주자!!