Skip to content

Passport GitHub 활용한 OAuth구현

YEJI HAN edited this page Jan 12, 2021 · 1 revision

목표

passport-github를 이용하여 GitHub 소셜 로그인 구현하기!

설계

  1. Social Login 서비스는 GitHub를 이용한다.
  2. Passport를 통해 인증 미들웨어방식을 사용하며, session을 통해 유저정보를 저장한다.
  3. 로그인페이지에서 GitHub 로그인 버튼을 클릭하면 GitHub 로그인으로 넘어간다.
  4. 소셜로그인이 완료되면 인증이 완료되며 루트페이지('/')에 접속할 수 있게 된다.
  5. 만약 로그인을 하지 않고 페이지에 접속하게 되면 로그인페이지로 redirect 된다.

GitHub Application 등록

GitHub Application 등록 image

  1. 다음과 같이 작성 후, Register application 클릭
  2. 이후 새롭게 만들어진 application 정보를 확인할 수 있는데, Client IDClient Secret 키는 Private하게 보관해야함! image

Passport 설치

npm i passport passport-github

Passport Strategy 작성

GithubConfig

const githubConfig = {
  clientID: process.env.GITHUB_CLIENT_ID,
  clientSecret: process.env.GITHUB_CLIENT_SECRET,
  callbackURL: 'http://127.0.0.1:3000/auth/github/callback',
};
  • clientID : Github 인증 생성시 받았던 클라이언트 ID
  • clientSecret : Github 인증 생성시 받았던 클라이언트 secret key
  • callbackURL : Github 인증 생성시 설정했던 URL

GithubLoginVerify

const githubLoginVerify = async (accessToken, refreshToken, profile, done) => {
  try {
    console.log('profile2 :', profile);
    const {
      _json: { id, login, node_id },
    } = profile;
    const userInfo = { id, login, node_id };
    return done(null, userInfo);
  } catch (err) {
    return done(null, false, { msg: '올바르지 않은 인증정보 입니다.' });
  }
};
  • accessToken : 받아온 인증 토큰
  • refreshToken : 토큰을 리프레시하여 새롭게 받아온 토큰
  • profile : Github에서 보내준 이용자의 프로필 정보
  • done(err, obj) : session에 저장하는 함수

serializeUser, deserializeUser

passport.serializeUser((user, done) => {
  done(null, user);
});
passport.deserializeUser((user, done) => {
  done(null, user);
});
  • serializeUser : 미들웨어는 전달받은 객체(정보)를 세션에 저장하는 역할 → deserializeUser로 전달
  • deserializeUser : 미들웨어는 서버로 들어오는 요청마다 세션 정보가 유효한 지를 검사하는 역할

passport.js 전체 코드

// passport.js
const passport = require('passport');
const { Strategy: GithubStrategy } = require('passport-github');

require('dotenv').config();

const githubConfig = {
  clientID: process.env.GITHUB_CLIENT_ID,
  clientSecret: process.env.GITHUB_CLIENT_SECRET,
  callbackURL: 'http://127.0.0.1:3000/auth/github/callback',
};

const githubLoginVerify = async (accessToken, refreshToken, profile, done) => {
  try {
    const {
      _json: { id, login, node_id },
    } = profile;
    const userInfo = { id, login, node_id };
    return done(null, userInfo);
  } catch (err) {
    return done(null, false, { msg: '올바르지 않은 인증정보 입니다.' });
  }
};

passport.serializeUser((user, done) => {
  done(null, user);
});
passport.deserializeUser((user, done) => {
  done(null, user);
});

module.exports = () => {
  passport.use('github', new GithubStrategy(githubConfig, githubLoginVerify));
};

Passport 등록 및 Session 설치

express-session 설치

npm i express-session
// app.js
const passport = require('passport');
const passportConfig = require('./passport/passport');
const session = require('express-session');
app.use(
  session({ secret: 'SECRET_CODE', resave: true, saveUninitialized: false })
);
app.use(passport.initialize());
app.use(passport.session());
passportConfig();

express-session을 설정해주며 passport의 세션을 초기화 한다

Login Router 작성

// routes/auth/index.js
const express = require('express');
const passport = require('passport');
const router = express.Router();

router.get('/github', passport.authenticate('github'));
router.get(
  '/github/callback',
  passport.authenticate('github', {
    failureRedirect: '/auth/fail',
    successRedirect: '/auth/success',
  })
);
  1. /auth/github에 Get 요청이 들어온 경우, passport에 github이라는 이름으로 등록된 미들웨어로 넘어가게 된다
  2. 로그인 성공시 /auth/success URL로 redirect되며
  3. 로그인 실패시 /auth/fail URL로 redirect 된다

Auth Middleware 작성

const isAuth = (req, res, next) => {
  if (req.isAuthenticated()) {
    next();
  }
  return res.status(301).redirect('/auth/fail');
};

성공적으로 소셜로그인을 하게 되었을 경우에는 다음과 같이 변수에 저장이 된다.

이를 이용하여 Auth Middleware를 작성할 수 있다

  • req.user : {id: 1234, login : 'name', node_id : 1234}
  • req.isAuthenticated : true
Clone this wiki locally