클론코딩/유튜브

#5 - Passport를 사용해 User Authentication하기

최문경 블로그 2020. 7. 4. 13:11

passport?

여권? 로그인 기능(+소셜 로그인 기능)을 만드는 데 도움을 주는 Node.js의 미들웨어!

 

사용자의 정보는 브라우저의 쿠키 안에 저장되어있는데, 

passport는 그것을 가져와서 user객체를 만들고 requset객체 안에 넣어준다.

그러면 우리는 그 user객체와 passport를 가지고 뚝딱뚝딱 로그인 기능을 만들 수 있는 것이다.

 

사용자가 로그인을 할 때는 두 가지 종류가 있다.

하나는 아이디와 비밀번호를 사용해서 로그인하는 것이고 (해당 사이트의 아이디, 비밀번호)

다른 하나는 구글, 페이스북, 깃허브와 같은 다른 소셜의 정보를 가지고 로그인하는 것이다.

 

passport에서는 첫번째 방식을 "local" 전략이라고 부르고

두 번째 방식은 "google", "facebook", "github" 등등 "소셜 이름" 전략이라고 부른다.

 

local strategy

설치

npm install passport passport-local passport-local-mongoose

 

User 스키마 만들기

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;

 

 

passport.js 만들기

// passport.js
import passport from "passport";
import User from "./modles/User";

passport.user(User.createStrategy());

// createStrategy는 아래의 코드를 줄인 것이라고 한다.
// passport.use(new LocalStrategy(
//   function(username, password, done) {
//     User.findOne({ username: username }, function (err, user) {
//       if (err) { return done(err); }
//       if (!user) {
//         return done(null, false, { message: 'Incorrect username.' });
//       }
//       if (!user.validPassword(password)) {
//         return done(null, false, { message: 'Incorrect password.' });
//       }
//       return done(null, user);
//     });
//   }
// ));

 

 

serializeUser, deserializeUser

serialization: 어떤 정보를 쿠키에게 주느냐 (쿠키가 어떤 정보를 가질 수 있느냐)(브라우저에게 어떤 정보를 주느냐)

import passport from "passport";
import User from "./modles/User";

passport.user(User.createStrategy());

passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

// 아래 코드가 요약하기 전 코드
// passport.serializeUser(function(user, done) {
//   done(null, user.id);
// });

// passport.deserializeUser(function(id, done) {
//   User.findById(id, function(err, user) {
//     done(err, user);
//   });
// });

 

 

사용자 등록하고 로그인 시키기

// globalRouter.js
globalRouter.post(routes.join, onlyPublic, postJoin, postLogin);

// userController.js
export const postJoin = async (req, res, next) => {
  const {
    body: { userName, email, password, password2 },
  } = req;
  if (password == password2) {
    try {
      // user 만들기 (mongoose)
      const user = await User({ name: userName, email });
      // user 등록하기 (passport-local-mongoose)
      await User.register(user, password);
      next();
    } catch (error) {
      console.log(error);
      res.redirect(routes.home);
    }
  } else {
    res.status(400);
    res.render("join", { pageTitle: "join" });
  }
};

export const postLogin = passport.authenticate("local", {
  successRedirect: routes.home,
  failureRedirect: routes.login,
});
// app.js
import passport from "passport";
import "./passport";

app.use(passport.initialize());
app.use(passport.session());