SNS 회원가입 및 로그인 - 구글

chu·2021년 4월 12일
1

이번 시간에는 전 시간처럼 SNS 회원가입 및 로그인에 대한 두번째 시간이다.
이번에는 구글을 통해서 회원가입 및 로그인 처리를 할 예정이다.

이번에도 passport를 통한 전략과 구글 개발 사이트에서 설정을 통해서
어떻게 진행되는지 알아보자.


Google

https://console.cloud.google.com/apis

이쪽으로 이동을 해주자. 코드작업 전 설정부터 해주면 빠르겠지?
페이지 이동 후 로그인을 하자. 로그인을 하고 프로젝트를 하나 생성해주자.
프로젝트 생성은 어렵지 않으니 생략하도록 하겠다.

그렇다면 아래와 같은 페이지가 나타난다. 물론 이미 설정을 한 상태이기 때문에 트래픽, 오류 등
여러 데이터가 UI로 노출된다. 그 전에 왼쪽 메뉴를 보면

사용자 인증 정보 OAuth 동의 화면 두 가지 메뉴가 있다. 이 중에 아래 OAuth 메뉴를
클릭해서 설정하자.

이동하게되면, User Type을 정하게 된다. 내부와 외부가 있지만, 내부는 클릭이 안된다. 그래서 외부를 일단 클릭해서 만들도록 하자.

그럼 아래 페이지로 이동을하게되고, placeholder 옆에 빨간 별표시가 들어간 부분에는
필수로 내용을 입력해주자.

그리고 위 메뉴인 사용자 인증 정보로 이동을 하자. 이동 후 가운데에 있는 사용자 인증 정보 만들기를 클릭해서 OAuth2.0 클라이언트 ID를 만들어주자. ID와 비밀번호가 생성된다.
ID와 비밀번호가 안보인다면, 우측에 연필표시(Edit)을 눌러서 확인 가능!

더 자세한 설정은 진행하지 않았다. 일단 필요한 설정이 어떤 부분이 있는지 모르기 때문이다.
그럼 이제 코드 작성에 대해서 정리하겠다.

passport-google

passport-google은 구글 로그인에 대한 전략을 설정한다. passport에 공식사이트에서
검색을 통해 찾아보자.

아래 이미지는 passport 공식사이트에서 google을 검색해서 나온 결과물이다.

아래에서 첫번째인 passport-google-oauth20를 보면 제일 다운로드 수가 높아서
저걸로 진행을 했다. 그럼 설치해주자.

install

npm i passport-google-oauth20

전 시간에 카카오톡에서 진행한 절차처럼 진행하면 된다. 공식문서에도 나오지만 구글 전략은
페이스북과 비슷하다고도 나오는데 내 생각에는 왠만한 SNS 방식은 다 비슷할 것 같다.

../routes/auth.js

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

const router = express.Router();

// 첫번째 코드 - 구글 로그인하기
router.get('/google', passport.authenticate('google', { scope: ['profile', 'email']}));

// 두번째 코드 - callback URL
router.get('/google/callback', passport.authenticate('google', {
  failureRedirect: '/',
}), (req, res) => {
  res.redirect('http://localhost:3000/');
});


module.exports = router;

여기서 카카오와 다른 점은 첫번째 코드에서 scope라는 부분이다. 패스포트 공식문서에서는 profile만 있길래 profile만 적어서 진행을 했는데... email을 가져오지 못하고 있는 것이다. 그래서 구글링을 통해서 찾아보니 저렇게 emailscope에 추가하니 가져올 수 있었다.

../passport/GoogleStrategy.js

구글 로그인에 대한 전략을 설정하는 코드다. 패스포트 공식문서를 꼭 참고하고 진행하자.
영어라서 모르겠다면 파파고에서 번역을 하거나, 페이지내에서 한국어 번역을 이용해서 공식문서를
참고하는 습관을 만들도록 하자.

const GoogleStrategy = require('passport-google-oauth20').Strategy;
const { User } = require('../models');
const passport = require('passport');

// 전략 코드
module.exports = () => {
  passport.use(new GoogleStrategy({
    clientID: process.env.GOOGLE_ID, // OAuth 클라이언트 ID
    clientSecret: process.env.GOOGLE_PASSWORD, // 위에서 같이 생성된 비밀번호
    callbackURL: "http://localhost:3051/auth/google/callback", // 콜백 URL
  }, async (accessToken, refreshToken, profile, cd) => {
    console.log('profile', profile);
    try {
      const exUser = await User.findOne({ // 이미 가입되어있는지? 체크
        where: { snsId: profile.id, provider: 'google' },
      });
      if (exUser) { // 있다면? -> 로그인
        cd(null, exUser); // 콜백
      } else { // 없다면?  -> 신규가입 후 로그인
        const newUser = await User.create({
          email: profile._json.email, // email
          nick: profile.displayName, // 이름
          provider: 'google', // 가입 출처
          snsId: profile.id, // sns ID (숫자로만 구성되어있음)
        });
        cd(null, newUser); // 콜백
      }
    } catch (error) {
      console.error(error);
      cd(error); // 콜백
    }
  }))
};

위 코드를 보면 알다시피 카카오 전략과도 정말 비슷하다. 당연히 passport에서 제공되는 것이니
비슷할 수 밖에 없겠지만, 위 auth.js에서 email을 처음에 가져오기 못했다고 했는데
어디서 확인을 해봤을까? 라는 생각이 들 수 있다. 그래서 카카오 시간에도 말했다시피

profile을 콘솔로 찍어서 데이터가 어떻게 담아져 있는지 확인해보자.

이렇게 진행이 되었다면 마지막 하나 더 체크를 해줘야한다.

../passport/index.js

const passport = require('passport');
const local = require('./localStrategy');
const kakao = require('./kakaoStrategy');
const google = require('./googleStrategy');
const { User } = require('../models');

module.exports = () => {
  // 로그인 성공 시 쿠키와 id만 들고있는다.
  passport.serializeUser((user, done) => {
    // null - 서버 에러
    // user.id - 성공해서 user의 id를 가져온다.
    done(null, user.id)
  });

  // 서버에서 유저에 대한 모든 정보를 갖고 있게되면, 서버 과부화가 생기게된다.
  // 그래서 서버는 id만 갖고있다가, 페이지 이동 시 필요한 유저 정보는 DB에서 찾아서 가져온다.
  // 그게 deserializeUser 역할이다.
  passport.deserializeUser( async (id, done) => { // DB에서 정보를 찾으면 req.user로 넣어준다.
    try {
      const user = await User.findOne({ where: { id }});
      done(null, user); // done 시 callback
    } catch(error) {
      console.error(error);
      done(error);
    }
  });

  local(); // 로컬 전략
  kakao(); // 카카오 전략
  google(); // 구글 전략
};

index.js에 하단에 꼭 해당하는 전략을 실행하도록 해야한다. 기재를 안하면 에러가 발생하니
발생 후 고쳐도 되지만, 미리 넣어두자😊

이렇게 구글로 로그인하는 방법에 대해서 작업을 진행했다.
다른 로그인도 해보고 싶지만, 중복된 작업일 것 같아서 일단 마무리하기로 하였다.

다른 프로젝트는 어떻게 해야할지 아이디어도 짜야하고, 깃에도 올리고 포트폴리오와 면접준비까지
빨리 진행을 해야하니까... 갈 길이 멀지만 ㅜ 빨리 가자😂

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

0개의 댓글