[express.js] Passport

김민재·2024년 4월 2일

express.js

목록 보기
17/39

전 내용 - 회원가입 및 로그인 ejs

passport 모듈 (미들웨어)

  • 여러가지 인증 처리 구현을 쉽게 도와준다(카카오, 구글, 페이스북, JWT)

    필요한 모듈 설치

    • npm i dotenv express nodemon body-parser cookie-parser cors mongoose passport passport-local passport-google-oauth20

      npm i passport-local 과 npm passport-google-oauth20의 차이점

      • passport-local은 유저네임/비밀번호를 이용한 인증 수단
      • google-oauth20은 구글 로그인(소셜 로그인)을 사용할 때 필요한 passport 모듈이다.

passport 사용법

  1. passport를 불러오고 passport 미들웨어를 설정한다.
const passport = require("passport");
// passport를 요청한다.

// passport 사용을 시작하고, 쿠키를 사용해서 인증을 처리하게 설정
app.use(passport.initialize());
app.use(passport.session());
// config 폴더에서 passport.js를 불러온다.
require("./config/passport");
  1. passport의 가독성을 높이기 위해 config라는 폴더를 만들고 passport.js 파일을 생성한다.

  2. passport.js 파일에 passport 코드를 작성한다.

const passport = require("passport");
const User = require("../models/user.model");
const LocalStrategy = require("passport-local").Strategy;

// req.logIn(user)
// app.js에서 req.login에서 user를 받아오고
// user 정보를 이용해서 세션을 생성하고 저장한다.
passport.serializeUser((user, done) => {
  done(null, user.id);
});

// client => session => request
// user.id를 이용해서 id를 가져오고
// done(null,user)를 이용해서 req.user = user를 이용한다.
passport.deserializeUser(async (id, done) => {
  await User.findById(id).then((user) => {
    done(null, user);

    // req.user = user; req.user에 user가 들어간다.
  });
});

// passport.use 무슨 전략을 사용할지(local)
passport.use(
  "local",
  new LocalStrategy(
    { usernameField: "email", passwordField: "password" },
    async (email, password, done) => {
      try {
        const user = await User.findOne({ email: email.toLocaleLowerCase() });

        if (!user) {
          return done(null, false, { msg: `Email ${email} not found` });
        }

        const isMatch = await user.comparePassword(password);

        if (isMatch) {
          return done(null, user);
        }

        return done(null, false, { msg: "Invalid email or password" });
      } catch (error) {
        done(error);
      }
    }
  )
);

  • passport-local은 유저네임과 비밀번호 인증 수단이다. 그래서 위 코드는 usernameField에 email를 받을 것이다.
  • email, password, done 여기서 done은 passport.authenticate에서 실행되는 부분이다. 4번
  • 회원가입 시 같은 이메일이 있으면 에러를 보낸다.
  • 등록된 email로 user가 없으면 msg를 보낸다.
  • 비밀번호 비교 함수(bcrypt 라이브러리를 사용하면 간편하다.)
  • 비밀번호가 다르면 err를 보내고 맞으면 user 정보를 보낸다.

3-1. comparePassword 함수(model 파일에)

userSchema.methods.comparePassword = async function (plainPassword) {
 return plainPassword === this.password;
};
  1. passport.js에서 만든 코드를 실행하는 코드

    //app.js
    // /login미들웨어 안에 authenticate 미들웨어가 또 있다.
    // 그래서 authenticate 미들웨어로 가기 위해서는
    // 66번째줄에 즉시 함수 실행을 해주면 된다.
    app.post("/login", (req, res, next) => {
     passport.authenticate("local", (err, user, info)    => {
     // passport.js에서 done
     if (err) {
       return next(err);
     }
    
     if (!user) {
       return res.json({ msg: info });
     }
    
     // passport에서 제공하는 함수 logIn
     req.logIn(user, function (err) {
       if (err) {
         return next(err);
       }
       res.redirect("/");
     });
    })(req, res, next);
    });
  • passport.js 에서 passport 함수를 만들고, 위 passport.authenticate 함수를 통해 실행을 받는다.
  • passport에서 제공하는 logIn함수를 통해 성공적으로 로그인이 가능하다.
  1. cookie-session을 이용해서 cookie에 유저 토큰을 저장하고 그것으로 어떤 유저인지 판별가능하다.
// app.js
app.use(
  cookieSession({
    name: "cookie-session",
    keys: [cookieEncryptionKey],
  })
);

// register regenerate & save after the cookieSession middleware initialization
app.use(function (request, response, next) {
  if (request.session && !request.session.regenerate) {
    request.session.regenerate = (cb) => {
      cb();
    };
  }
  if (request.session && !request.session.save) {
    request.session.save = (cb) => {
      cb();
    };
  }
  next();
});

로그인이 성공하게 되면

cookie에 cookie-session이 저장된다.

깃허브 소스 코드

profile
개발 경험치 쌓는 곳

0개의 댓글