전반적인 흐름

image.png

image.png

0. 깃허브 인증앱 만들기

1. passport-github 설치 & User 모델 파일 작성

passport.js

import routes from "./routes";
import passport from "passport";
import GithubStrategy from "passport-github";
import User from "./models/User";
import { githubLoginCallback } from "./controllers/userController";

passport.use(User.createStrategy());

passport.use(
    new GithubStrategy({
        clientID: process.env.GH_ID,
        clientSecret: process.env.GH_SECRET,
        callbackURL: `http://localhost:4000${routes.githubCallback}`
    },
        githubLoginCallback
    )
);
...
  • passport-github 인스톨을 passport.js 파일에 설치
  • GithubStrategy strategy 생성 (env 파일을 이용해 개인정보보완)

User.js

import mongoose from "mongoose";
import passportLocalMongoose from "passport-local-mongoose";

const UserSchema = new mongoose.Schema({
    name: String,
    email:String,
    avatarUrl: String,
    facebookId: Number,
    githubId: Number
});
UserSchema.plugin(passportLocalMongoose,
    {usernameField:"email"},
);
const model = mongoose.model("User",UserSchema);

export default model;
  • 깃헙으로부터 담을(사용할) 변수 지정한 UserSchema 모델 생성
  • passportLocalMongoose 플러그인을 이용하여 usernameField를 email로 지정 (이메일이 곧 로그인 아이디가 됨)

3. routes 생성

routes.js

// Github

const GITHUB = "/auth/github";
const GITHUB_CALLBACK = "/auth/github/callback";

 gitHub: GITHUB,
 githubCallback: GITHUB_CALLBACK
  ...

4. router & controller

globalRouter.js

import express from "express";
import passport from "passport";
import routes from "../routes";
import { postJoin, getLogin, logout, getJoin, postLogin, githubLogin, postGithubLogIn } from "../controllers/userController";
...
globalRouter.get(routes.gitHub, githubLogin);
globalRouter.get(
    routes.githubCallback,
    passport.authenticate("github", { failureRedirect: "/login" }),
    postGithubLogIn
);
  • 4-1. 깃허브 인증페이지링크로 이동,
    githubLogin = passport.authenticate("github".... 깃허브 로그인 인증을 한다
  • 4-2. passport.js에 있는 GitHubStrategy 이용,
    깃헙페이지로 갔다 돌아올때 callbackURL(routes.githubCallback)로 돌아오면서 사용자정보를 얻음
  • 4-3. callbackURL로 돌아오면
    passport.js에 있는 githubLoginCallback 사용
  • 4-4. 로그인이 성공이고 githubLoginCallback 함수를 성공적으로 리턴하면
    postGithubLogin 실행

userController.js

import passport from "passport";
import routes from "../routes";
import User from "../models/User";
...
export const githubLogin = passport.authenticate("github");
export const githubLoginCallback = async (_, __, profile, cb) => {
    ...
};
export const postGithubLogIn = (req, res) => {
    res.redirect(routes.home);
};

5. 깃허브로그인콜백 함수에서 유저/비유저 판별

userController.js

...
export const githubLoginCallback = async (_, __, profile, cb) => {
    const {
      _json: { id, avatar_url, name, email }
    } = profile;
    try {
    // 1
      const user = await User.findOne({ email });
      if (user) {
        user.githubId = id;
        user.save();
        return cb(null, user);
      }
    // 2
      const newUser = await User.create({
        email,
        name,
        githubId: id,
        avatarUrl: avatar_url
      });
      return cb(null, newUser);
    } catch (error) {
      return cb(error);
    }
  };
  ...
  • 1 : 깃허브인증 메일과 User 모델이 갖고 있는 email이 같다면
    깃허브유저id 값을 User 모델 id값과 동일하게 만든다
  • 1: 유저 저장
  • 1: cb(에러없음, user리턴)
  • 2: User를 새로 생성 (email(스키마 변수) : email(깃헙) 정보 설정)
  • 2: cb(에러없음, newUser리턴)