Next.js 카카오 로그인 구현하기 (w spring) (1)

moreas·2023년 3월 31일
3

팀 프로젝트

목록 보기
6/14
post-thumbnail

어떤 글을 쓸 거냐면

  • next.js와 스프링 협업으로 카카오 로그인 구현하기
  • 프론트엔드단의 구현 과정에서 oauth 소셜 로그인 경험한 것을 기록
  • 사용한 기술: next.js, react, typescript, redux toolkit
  • 정말 무수히 많은 문서와 블로그 글을 봤다. 잘못된 방법도 있었고 진행 과정에서 조금씩 방법론이 다 다르기 때문에 더 헷갈리고 어려웠다. ㅠㅠ
  • 내 글이 정답이 아니기 때문에 참고 정도만 하시기를 부탁드린다.

🏊🏻 과정

Spring-React-카카오-소셜-로그인-JWT
스프링과 협업을 하신다면 참고하기 좋은 블로그.
백엔드와 소통을 원활히 하기 위해 백엔드 과정도 이해하고 싶다면 이 블로그를 추천한다.
수많은 로직보다는 텍스트가 있어서 백엔드 지식이 많지 않은 본인에게도 로그인 과정을 이해하는 데 도움이 됐다.

우리는 oauth를 이용한 카카오 소셜 로그인을 사용할 것이고 JWT 토큰을 이용할 것이다.



🧤로그인

getting start

REST-API 활용한 카카오 소셜 로그인 구현(feat. React)
이 블로그에서 설명한 과정을 가장 많이 참고했다. 감사합니다 :,)

  • 카카오 디벨로퍼에서 설정하는 건 검색만 해봐도 많이 나오기 때문에 생략하겠다.
  • 중요한 점은 백이나 프론트 둘 중 한 사람이 설정한 REST API KEY, 도메인, 리다이렉트 uri를 따라가야 한다는 것이다.
  • 리다이렉트 uri는 카카오 로그인 시작하기 화면에서 로그인을 눌렀을 때 전환되는 화면, 즉 프론트엔드단에서 사용하는 것이기 때문에 프론트에서 원하는 uri 경로를 사용하거나, 협의를 통해 결정한다.

카카오 url로 로그인 화면 접속하기

// kakao_login
const KAKAO_REST_API_KEY = process.env.KAKAO_CLIENT_ID;

const KAKAO_REDIRECT_URI = "http://localhost:3000/login/kakao";

export const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${KAKAO_REST_API_KEY}&redirect_uri=${KAKAO_REDIRECT_URI}&response_type=code`;

  • 변수로 지정하여 로그인 버튼을 누르면 카카오 로그인 화면으로 이동하도록 만들었다.
  • 보안에 민감한 키들은 환경변수로 지정하여 꺼내썼다.


인가코드 백엔드로 보내기

let code = new URL(window.location.href).searchParams.get("code");
const response = await axios.get(
         `${API 서버 주소}/oauth/token?code=${code}`,
         { withCredentials: true }
       );
  • 카카오 로그인 화면에 접속하여 로그인버튼을 누르면 우리가 지정한 리다이렉트 uri로 이동한다.
  • url을 확인하면 이런 식으로 해당 uri 뒤에 붙은 코드가 있다. 이걸 백엔드로 보내야 한다. (보내주면 응답으로 토큰이 온다!)
http://localhost:3000/login/kakao?code=긴 코드
  • 리다이렉트 페이지 경로에 대한 프론트엔드 쪽 컴포넌트를 만들지 않으면 404에러 페이지가 뜬다. 해당 경로에 접속했을 때 뜨는 화면을 설정해야 404가 뜨지 않고 코드를 추출할 수 있다.
  • 예를 들어, 나는 'localhost3000/login/kakao' 를 리다이렉트 경로로 설정했기에 pages > login > kakao.tsx 에서 원하는 로직을 작성해주었다. 이걸 쉽게 설명해주는 곳이 없어서 많이 헤매고 이해가 안갔는데 다 하고 나니까 쉽게 느껴지더라 ㅎ..
  • 쿼리 스트링으로 코드를 전달한다.


토큰 받기

axios 공식문서

  • axios를 사용한 try catch문을 많이 사용하고 있다.
  • 쿠키 사용을 위해 라이브러리를 설치했다. 정말,, 로그인 유지에 많이 헤매서 온갖 쿠키 라이브러리를 썼지만 최종적으로 사용한 건 react-cookies다. react-cookie 라이브러리도 있는데 next.js에서는 사용이 되지 않았다.

    yarn add react-cookies

const response = await axios.get(`/oauth/token?code=${code}`, {
          withCredentials: true,
        });
        const { accessToken } = response.data;
        const { refreshToken } = response.data;
        cookie.save("accessToken", accessToken, {
          path: "/",
        });
        cookie.save("refreshToken", refreshToken, {
          path: "/",
        });
        setToken;
        dispatch(setToken(accessToken));
  • 코드를 보내고 난 후 response로 토큰이 오기 때문에 이걸 받아서 쿠키에 저장한다. 리덕스에도 액세스토큰만 저장을 했다.



로그인 정보 받아서 헤더에 띄우기

  • 쿠키에 저장된 토큰을 불러와서 유저정보를 요청한다.
  • 받은 데이터의 유저정보를 헤더에 띄운다.
  const accessToken = cookie.load("accessToken");


useEffect(() => {
    console.log(accessToken);
    const response = async () => {
      if (accessToken) {
        const userRes = await axios.get(`/loginInfo`, {
          headers: {
            "Access-Token": accessToken,
          },
          withCredentials: true,
        });
        const { id, nickName, email } = userRes.data.data;
        dispatch(setId(id));
        dispatch(setEmail(email));
        dispatch(setNickname(nickName));
        setUser(userRes.data.data);
        console.log(userRes.data.data);
      }
    };
    response();
  }, [accessToken]);
  • 이 과정에서 받아온 데이터를 추출해서 콘솔에 찍어봤는데 undefined를 만났다. 네트워크는 200이 떴는데 이상해서 한참 헤맸다.
  • userRes.data가 아닌 userRes.data.data 안에 있었다. ^^ ,,,,;
  • 받아오는 데이터를 잘 살펴보자,..

🌐 로그아웃

  • 로그아웃 버튼을 누르면 쿠키에 저장한 액세스 토큰과 store에 저장된 정보들을 삭제한다.
  const handleLogout = () => {
    cookie.remove("accessToken", { path: "/" });
    dispatch(setToken(""));
    dispatch(setNickname(""));
    dispatch(setEmail(""));
    dispatch(setId(0));
  };


느낀 점

  • 처음으로 백엔드와 협업, API 통신을 해봤는데 너무 재미있고 뭔가를 만들어나간다는 생각에 되게 성취감이 많이 생겼다.
  • 그런데 이 단계를 오기까지 정말 수많은 좌절이 있었다. 프론트 백 지식 모두 부족하다고 생각이 들었고, 계속 뭔가를 검색하면 새로 공부해야하는 늪에 빠져 있었기 때문에 좌절감도 많이 겪었다. 결과적으로 완벽하진 않지만 기능을 구현했을 때는 정말 너무 기뻤다.
  • 시행착오를 겪고 나서 얻은 지식은 정말 도움이 많이 된다.
  • 기타 CORS 설정 등에 관련해서는 다음 포스트 때 써보겠다.


하지만 여기서 문제가 있었다. ㅠㅠ
-다음 이 시간에,,, -

profile
Everything is connected 🐶 좀 더 나은 개발을 위해

1개의 댓글

comment-user-thumbnail
2023년 7월 14일

정보도 얻어가고 내용도 흥미진진하네요 .. 👍

답글 달기