본문 바로가기
경일/nodejs

[node.js] kakao(카카오) OAuth 2.0 로그인 기능

by dev_kong 2022. 3. 16.
728x90
728x90

0.목차

1. 개요

2. 카카오 디벨로퍼

3. 기능개발

1. 개요

드디어 OAuth 2.0 을 기반으로 한 소셜로그인 기능을 구현 해본다.
제일 해보고 싶었던 것 중에 하나라
하는 내내 재밌게 할 수 있었다.

2. 카카오 디벨로퍼

우선 카카오 디벨로퍼 사이트에 들어가서 카카오 로그인을 한 뒤,

커다란 시작하기 버튼을 눌러주자.

애플리케이션을 추가하기를 누른뒤에

필요한 정보들을 입력해주자

그리고 생성한 애플리케이션을 클릭하면

이런 애가 나온다.

여기서 기억해야될 내용은 REST API 키 이다. 소중하게 잘 보관하자.

여기로 들어오면

이런내용이 보인다.

수정 버튼을 눌러서

카카오 로그인 이후 이동할 페이지를 적어주자

그리고 저 redirect URI 도 잘 보관해두자.

이번엔 일로 가면 된다.

여기가면

이런 애가 있다.

코드 옆에 발급버튼을 눌러서 코드를 발급받고

활성화 상태를 사용함으로 변경해주면 된다.

그럼이제 준비는 끝났다

vscode 키면 된다 신난다.

3. 기능개발

시작 전에 데이터가 어떻게 전송되고 요청과 응답이 주고받아지는지

전체적인 흐름을 먼저 보고

머릿속에 저장해두면 코드를 이해하는 데 큰 도움이 될거 같다.

그림 그릴 생각에 손발이 저려온다.

와... 이거 이상으로 잘 그릴 자신이 없다.

코드를 보면서 하나하나 풀어보자

1번

브라우저 즉 클라이언트에서 a 태그를 통해 /auth/kakao에 GET요청을 보낸다.

<a href="/auth/kakao">카카오로그인</a>

그러면 서버는 응답을 통해 클라이언트를 redirect 시켜준다.

// routes/kakaoLogin.js

const kakaoOpt = {
  clientId: 'rest API 키',
  clientSecret: 'client Secret code',
  redirectUri: 'redirect URI',
};


router.get('/kakao', (req, res) => {
  const kakaoLoginURL = `https://kauth.kakao.com/oauth/authorize?client_id=${kakaoOpt.clientId}&redirect_uri=${kakaoOpt.redirectUri}&response_type=code`;
  res.redirect(kakaoLoginURL);
});

위에서 잘 저장해두었던 세가지 값으로 kakaoOpt 라는 객체를 만들어서 사용한다.

2번

리다이렉트를 통해 해당 주소로 GET요청을 보낸 클라이언트는
카카오 서버로 부터 카카오 로그인페이지가 마크업 돼있는 HTML을 전달한다.

브라우저가 기본적으로 카카오로그인이 되어있다면 바로 이런 모습이 랜더가 될것이고

아니라면 카카오 아이디와 비밀번호를 입력하게끔 되어있을거다.

3번

위의 사진에서 동의하고 계속하기를 누르면
카카오서버로 요청을 보내고
카카오서버는 응답을 통해 클라이언트를 리다이렉트 시킨다.

여기서 리다이렉트 시키는 주소는 kakaoOpt.redirectUri 이다.

4번

클라이언트는 kakaoOpt.redirectUri에 적혀있는 주소를 백엔드에 GET 요청을 보낸다.
그러면 백엔드에선 액시오스를 통해 4-1번 4-2번 내용을 카카오서버와 직접 통신한다.

router.get('/kakao/callback', async (req, res) => {
  let token;
  try {
    const url = 'https://kauth.kakao.com/oauth/token';
    const body = qs.stringify({
      grant_type: 'authorization_code',
      client_id: kakaoOpt.clientId,
      client_secret: kakaoOpt.clientSecret,
      redirectUri: kakaoOpt.redirectUri,
      code: req.query.code,
    });
    const header = { 'content-type': 'application/x-www-form-urlencoded' };
    const response = await axios.post(url, body, header);
    token = response.data.access_token;
  } catch (err) {
    console.log(err);
    console.log('에러1');
    res.send('에러1');
  }

  try {
    const url = 'https://kapi.kakao.com/v2/user/me';
    const Header = {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    };
    const response = await axios.get(url, Header);
    const { nickname, profile_image: img } = response.data.properties;
    const payload = { nickname, img };
    const accessToken = makeToken(payload);
    const cookiOpt = { maxAge: 1000 * 60 * 60 * 24 };
    res.cookie('accessToken', accessToken, cookiOpt);
    res.send(alertmove('/', `${nickname}님 로그인 되었습니다^^`));
  } catch (err) {
    console.log(err);
  }
});

첫번째 try문이 4-1의 내용이다.
주의할 점은 content-type이 application/x-www-form-urlencoded 지정되어있기 때문에
body의 내용을 쿼리스트링으로 만들어야 한다.
일일이 쿼리스트링을 적기 귀찮으니까 객체로 만든뒤에
객체를 쿼리스트링으로 만들어 주는 외부라이브러리인 qs를 이용해 쿼리스트링을 만들어 주었다.

그리고 해당 url에 포스트 요청을 보내면 카카오 서버는 토큰을 만들어서 백엔드 서버에 토큰을 전달해준다.

그리고 두번째 try문이 실행되는데 여기가 4-2의 내용이다.
4-1 에서 전달 받은 토큰을
Bearer 형태의 토큰으로 만들어서 req header에 담아 요청을 보낸다.

요청을 받은 서버는 해당 토큰과 일치하는 사용자의 정보를 백엔드에 전달해준다.
백엔드는 해당 정보를 받아서 jwt 라이브러리를 이용해 토큰을 만들었다.

그리고 마지막으로 만들어진 토큰을 쿠키로 전달하면서 res.send를 통해 클라이언트에 4번요청에 대한 응답을 준다.

전체코드는 깃헙에 있다.

728x90
728x90

댓글