티스토리 뷰

1️⃣ gptea 로그인 / 로그아웃 

네이버/카카오 access_token을 받고 gptea 서버로 보내면 gptea access_token을 발급해준다.
gptea access_toekn을 로컬스토리지에 저장해주고, 앞으로 gptea api 요청시 헤더를 다음처럼 토큰을 포함시키도록 작성한다.

 headers: {
   Authorization: 'Bearer GPTEA_ACCESS_TOKEN',
 },

 

gptea api의 /register 요청으로 사용자를 등록하고 /sign-in 요청으로 로그인을 한다.
/sign-in 요청시 사용자가 아니라는 에러가 발생하면 /register 요청을 하고 다시 /sign-in 요청을 하도록 구현했다.

네이버/카카오 로그인 버튼을 누르면,
네이버/카카오 access_token 발급 → gptea access_token 발급(getGpteaToken, registerInGptea) → 로그인 상태 true 갱신 → 로그인된 홈페이지로 리다이렉트
과정이 연쇄적으로 일어나기 때문에 getGpteaToken 함수와 registerInGptea 함수는 동기적으로 프로미스를 반환하도록 했다.

로그아웃은 gptea access_token을 로컬스토리지에서 삭제하고 로그인 상태를 false로 갱신하도록 했다. 로그인할 때 이용한 네이버/카카오 소셜로그인의 access_token도 로컬스토리지에서 삭제해준다.

 

🙌 github commit 🙌

 

feat: add GPTEA login and logout, fix/refactor: NAVER and KAKAO · evergarden0412/gptea-web@a56c5d9

Show file tree Showing 9 changed files with 159 additions and 52 deletions.

github.com

 

 

2️⃣ fetch API 를 axios 로 변경하기

axios로 바꾼 이유는 다음과 같다.

1. axios에서 JSON으로 직렬화/역직렬화를 자동으로 해주어 JSON.stringify 와 .json()을 사용하지 않아 코드를 줄일 수 있다.

2. axios의 프로미스는 응답코드가 200대가 넘어가면 reject해주는 반면, fetch는 네트워크 장애가 있을 때에만 reject하기 때문에 400코드를 응답받아도 catch메서드가 아닌 then메서드가 실행된다. then메서드에서 status 별로 분기하여 핸들링해주어야 한다.
다음과 같이 then메서드에서 별도로 핸들링해주지 않고 catch메서드만 사용하면 400코드를 받았는데도 성공 로직이 실행되어 logged in! 이 출력된다. 

// fetch API
export const getGpteaToken = (accessToken: string, social: string): Promise<void | string> => {
  return new Promise((resolve, reject) => {
    fetch('/auth/cred/sign-in', { method: 'POST', body: JSON.stringify({ accessToken, cred: social }) })
      .then((response) => {
        if (response.status === 200) {
          return response.json();
        } else throw new Error(ERROR_GET_GPTEA_TOKENS);
      })
      .then((json) => {
        if (!localStorage.getItem(GPTEA_ACCESS_TOKEN)) {
          localStorage.setItem(GPTEA_ACCESS_TOKEN, json.accessToken);
        }
        resolve();
      })
      .catch((error) => {
        console.log(error);
        registerInGptea(accessToken, social).catch((error) => reject(error));
      });
  });
};
// axios
export const getGpteaToken = (accessToken: string, social: string): Promise<void | string> => {
  return new Promise((resolve, reject) => {
    axios('/auth/cred/sign-in', { method: 'POST', data: { accessToken, cred: social } })
      .then((response) => {
        const { accessToken } = response.data;
        if (!localStorage.getItem(GPTEA_ACCESS_TOKEN)) {
          localStorage.setItem(GPTEA_ACCESS_TOKEN, accessToken);
        }
        resolve();
      })
      .catch((error) => {
        console.log({ ERROR_GET_GPTEA_TOKENS, error });
        registerInGptea(accessToken, social).catch((error) => reject(error));
      });
  });
};

참고한 블로그에 fetch API와 axios의 차이에 대해 잘 나와있다.

 

🔨 한 편, fetch API에서 {mode: no-cors} 옵션으로 CORS에러를 회피했는데, axios에는 해당 옵션을 제공하지 않는다. 네이버 로그인 API에서 발생한 CORS에러였는데, 이미 gptea 백엔드 서버를 프록시 설정해주었기 때문에 프록시를 여러개 설정할 수 있도록 http-proxy-middleware를 설치하여 추가해주었다.
해당 내용은 하단의 CORS 에러 해결 포스팅에 작성하였다.

 

React CORS에러 클라이언트에서 해결하기, proxy 2개 설정하기

1. package.json에 proxy 추가하기 CORS에러가 떴다. 응답받을 서버 주소와 내가 요청하는 로컬호스트의 출처가 서로 달라서 생긴 문제이다. 프록시서버를 두어 프록시가 요청하고 프록시가 응답해주

hahagarden.tistory.com

 

🙌 github commit 🙌

 

feat: change fetchAPI into axios and add proxy · evergarden0412/gptea-web@e6d0450

Show file tree Showing 11 changed files with 133 additions and 77 deletions.

github.com

 

3️⃣ 다음 할 일

Redux 도입하기
gptea access_token verify하기
gptea access_token 만료되면 refresh_token 사용하기
Chat 추가하기 버튼 만들고, Chat 추가하고 불러오는 api요청 구현하기

 

 

반응형
댓글