SNS 회원가입 및 로그인 - 카카오

chu·2021년 4월 12일
3

이번 시간에는 SNS로 회원가입과 로그인 구현에 대해서 정리를 하겠다.

한국에서 자주 쓰이는 카카오구글로 구현을 했다.


passport를 이용하여 구현을 진행하였다.
passport에는 SNS에 대해서 많은 기능을 가지고 있다.

카카오, 구글, 페이스북, 트위터, 링크드인 등... 한번 써볼까?

kakao

install

npm i passport-kakao

카카오 개발 앱 설정

그리고 잠시 카카오개발사이트에서 설정을 해야한다.
먼저 페이지에서 개인 카카오 계정으로 로그인을 하자.

로그인을 했다면 위 이미지에서 노란색 테두리 박스에 있는 내 애플리케이션 을 클릭!
그럼 아래 이미지가 있는 페이지로 이동된다.

이미 만든 애플리케이션이 있기 때문에 추가 생성은 하지 않지만, 없는 분이 계시다면 추가해주자.
추가에 필요한 정보는 아무거나 작성해도 상관없다.

위 페이지는 생성한 애플리케이션으로 이동하면 왼쪽 햄버거버튼에서
플랫폼을 클릭하면 나오는 페이지다.

아래 Web에서 사용할 사이트 도메인을 추가해주자.
그 후 바로 아래에 써있는 Redirect URI를 등록하고자 등록하러가기 클릭!

위 처럼 활성화 설정 - ON으로 설정해주고, 아래에 있는 Redirect URI서버주소/ouath를 추가해주자.
이 부분은 주소가 개발자마다 다를 순 있다. 하지만 passport 공식문서에서 카카오 설정에는
Redirect URIouath로 하는걸 권장한다고 한다.

그리고 왼쪽 햄버거 메뉴에서 앱 키 메뉴를 클릭해서 이동된 페이지를 확인해보자.
여러 키들이 있지만, 여기서 REST API 키를 사용하기 때문에 복사를 해주자.
이 키는 .env에 넣기 때문에 노출이 되서는 안된다.

위 페이지는 햄버거 메뉴에 있는 카카오 로그인에서 동의항목 메뉴를 클릭하면 이동된다.
간단하게 프로필 정보와 카카오계정(이메일)만 설정해주도록 하자.
어렵지 않기 때문에 설정에서 원하는 조건에 맞게 설정을 해주자.

자! 이제 설정은 끝! 코드를 시작 해보자!

npm 설치를 해준 뒤 passport 폴더에 kakaoStrategy.js 라는 파일을 생성해주자.

../passport/kakaoStrategy.js

const passport = require('passport');
const KakaoStrategy = require('passport-kakao').Strategy;

const User = require('../models/user');

// 카카옥 로그인 전략
module.exports = () => {
  passport.use(new KakaoStrategy({
    clientID: process.env.KAKAO_ID, // 이것이 REST API KEY
    callbackURL: 'http://localhost:3051/ouath', // Redirect URI
  }, async (accessToken, refreshToken, profile, done) => {
    // accessToken, refreshToken - OAUTH2 를 공부해야한다.
    // 그래서 여기선 사용하지 않는다.
    console.log('kakao profile', profile); // 꼭 확인해보자!
    try {
      const exUser = await User.findOne({ // 카카오 가입자 찾기.
        where: { snsId: profile.id, provider: 'kakao'},
      });
      if (exUser) { // 가입자 있으면? 로그인 성공
        done(null, exUser);
      } else { // 없으면? 생성 후 로그인 시키기
        const newUser = await User.create({
          // id - Number이며, 사용자의 kakao id
          // _json - 사용자 정보 조회로 얻은 json 원본 데이터
          email: profile._json && profile._json.kakao_account.email,
          nick: profile.displayName,
          snsId: profile.id, // 새로 추가한 sns Id 컬럼
          provider: 'kakao', // 새로 추가한 가입 출처 컬럼
        });
        done(null, newUser);
      }
    } catch(error) {
      console.error(error);
      done(error);
    }
  }));
}

else 가입자 생성에서 profile에 대한 정보는
console.log('kakao profile', profile)로 꼭 확인해보고 해당되는 데이터를 가져와서 쓰자.

배울때는 데이터 경로가 달랐다. 카카오에서도 데이터에 대한 경로를 바꾸는 것 같다.
그러니 꼭 확인해보면 좋겠지?

이렇게 카카오 로그인 전략은 완성이다. 이게 라우트를 작업해보자.

../routes/auth.js

const express = require('express');
const passport = require('passport');

const router = express.Router();

// 카카오 로그인하기
// GET /auth/kakao/
// 최초 카카오 Strategy가 실행되면, 카카오 로그인부터 시작을 해야하고,
// 카카오 로그인 페이지에서 로그인하면 콜백URI로 이동을 한다.
router.get('/kakao', passport.authenticate('kakao', {
  failureRedirect: '/', // 실패했을 경우 리다이렉트 경로
}));

// 구글 로그인하기 이미 구현했지만 코드는 다음에...

module.exports = router;

너무 허무하단 생각은 들지만 사실 경로를 뒤죽박죽으로 잡아서 추가 코드가 있다...ㅎ

../routes/page.js

const express = require('express');
const passport = require('passport');

const router = express.Router();

// 카카오 개발 앱 설정 중 Redirect URI에 적는 주소
// GET /ouath
// 카카오 로그인 페이지에서 로그인 후 아래에서 카카오 Strategy가 실행되며,
// kakao.js 모듈 실행
router.get('/ouath', passport.authenticate('kakao', {
  failureRedirect: '/',
}), (req, res) => {
  res.redirect('http://localhost:3000'); // 다 완료되면 리다이렉트 URL
});

module.exports = router;

이번에도 중요한건 코드가 아닌 흐름이다. 최초 실행은 위에 코드인 router.get('/kakao') 가 실행이 된다. passport.authenticate('kakao')를 발견하고, 카카오 로그인 전략을 실행한다.

passport.use(new KakaoStrategy({
  clientID: process.env.KAKAO_ID, // 이것이 REST API KEY
  callbackURL: 'http://localhost:3051/ouath', // Redirect URI
}, ... );

이 부분이 실행되며, callbackURL에서 다시
router.get('/ouath', passport.authenticate('kakao', 이 부분이 실행이 된다.

그럼 이 부분이 실행하게 된다.

async (accessToken, refreshToken, profile, done) => {
  // accessToken, refreshToken - OAUTH2 를 공부해야한다.
  // 그래서 여기선 사용하지 않는다.
  console.log('kakao profile', profile); // 꼭 확인해보자!
  try {
    const exUser = await User.findOne({ // 카카오 가입자 찾기.
      where: { snsId: profile.id, provider: 'kakao'},
    });
    if (exUser) { // 가입자 있으면? 로그인 성공
      done(null, exUser);
    } else { // 없으면? 생성 후 로그인 시키기
      const newUser = await User.create({
        // id - Number이며, 사용자의 kakao id
        // _json - 사용자 정보 조회로 얻은 json 원본 데이터
        email: profile._json && profile._json.kakao_account.email,
        nick: profile.displayName,
        snsId: profile.id, // 새로 추가한 sns Id 컬럼
        provider: 'kakao', // 새로 추가한 가입 출처 컬럼
      });
      done(null, newUser); // done 시 콜백된다.
    }
  } catch(error) {
    console.error(error);
    done(error);
  }
}));
}

위 전략을 모두 마치게되면

router.get('/ouath', passport.authenticate('kakao', {
  failureRedirect: '/',
  // 아래 부분이 실행되면서 끝난다.
}), (req, res) => {
  res.redirect('http://localhost:3000'); // 다 완료되면 리다이렉트 URL
});

이렇게 카카오 회원가입 및 로그인에 대한 코드는 끝이다. 위 작성법대로 진행을 하게되면,
최초 카카오 로그인 시 카카오에서 제공되는 카카오 로그인 페이지 창이 뜬다.
거기서 개인의 카카오 계정으로 로그인을 하고, 카카오 개발 사이트에서 설정한 개인정보 동의항목에
따라서 체크를 하고, 회원가입 및 로그인이 실행된다.

만약 여기서 추가 정보를 얻고 싶다면? 카카오에서 제공을 해주지 않은 상태에서 말이다.
물론 개인정보보호에서 설정에서는 실제 상업용도라면 추가적으로 동의선택을 추가할 수 있다.

그 별도로 로컬에서 정보를 추가 입력하도록 만들려면, 미들웨어에서 추가하거나, 혹은 리다이렉트를
추가 정보를 입력하는 페이지로 이동시킨 후 회원가입을 완료시키면 될 것 같다.

이 부분은 추후 추가적인 기능을 만들어보도록 하자.

React에서 어떻게 처리할까?

여기서 리액트는 프론트에서 어떻게 SNS 로그인을 처리할까다.. 처음에 여기서 시간을 좀 잡아먹었다. 하지만 방법은 정말 너무나 간단했다. API로 요청을해서 진행을 할 것 같지만 아니다.

이번 프로젝트에는 Next를 사용을 했기 때문에 Next를 이용해서 링크 이동할 것이다.
여기서 Link는 Next에서 불러온 Link다. 그리고 Link안에 a태그를 넣어준다.
전에는 그런적이 없지만 안넣어주니 에러가 발생을 했다.

그리고 링크 주소는 서버주소/auth/kakao 넣어줬다. 이렇게 하면 진행 끝!

import Link from 'next/Link';
<SnsSignupBox> <!--@emotion_styled-->
  <h2>SNS 간편 로그인</h2>
  <div>
    <Link href="http://localhost:3051/auth/kakao">
      <a>
        <RiKakaoTalkFill className="kakao-btn" />
      </a>
    </Link>
    <Link href="http://localhost:3051/auth/google">
      <a>
        <RiGoogleFill className="google-btn" />
      </a>
    </Link>
  </div>
</SnsSignupBox>

다음 시간에는 SNS 회원가입 및 로그인 두번째로 구글 로그인에 관련해서 정리하고,
회원가입 및 로그인에 대한 내용은 마무리하고, 다음 프로젝트에 대해서 진행할 예정이다.

profile
한 걸음 한걸음 / 현재는 알고리즘 공부 중!

0개의 댓글