[node js] passport

seokki kwon·2022년 10월 16일
0

passport 모듈을 사용하여 세션로그인 구현해보기

express-session

express-session 을 미들웨어로 사용하면 세션객체를 받을 수 있다
확인방법은 req.session

app.use(
  session({
    resave: false,
    saveUninitialized: false,
    secret: process.env.COOKIE_SECRET,
    cookie: {
      httpOnly: true,
      secure: false,
    },
  })
);

passport 사용

const express = require("express");
const cookieParser = require("cookie-parser");
const morgan = require("morgan"); 
const path = require("path");
const session = require("express-session");
const nunjucks = require("nunjucks");
const dotenv = require("dotenv");
const { sequelize } = require("./models");
const passport = require("passport"); // passport 불러오기
const pageRouter = require("./routes/page");
const passportConfig = require("./passport"); // passportConfig 함수 불러오기
// config
dotenv.config(); // dotenv.config() 함수를 호출하고 나면 .env 의 환경변수를 읽을 수 있다.

const app = express();

// nunjucks
app.set("port", process.env.PORT || 8001);
app.set("view engine", "html");
nunjucks.configure("views", {
  express: app,
  watch: true,
});

passportConfig();
app.use(morgan("dev"));
app.use(express.static(path.join(__dirname, "public")));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET));

sequelize
  .sync({ force: false })
  .then(() => {
    console.log("database sync model");
  })
  .catch((err) => {
    console.error(err);
  });

app.use(
  session({
    resave: false,
    saveUninitialized: false,
    secret: process.env.COOKIE_SECRET,
    cookie: {
      httpOnly: true,
      secure: false,
    },
  })
);

app.use(passport.initialize()); // req객체엥 passport 설정을 심는다
app.use(passport.session()); // req.session 객체에 passport 정보를 저장

app.use("/", pageRouter);

app.use((req, res, next) => {
  const error = new Error(`${req.method} ${req.url} 라우터가 없습니다.`);
  error.status = 404;
  next(error);
});

app.use((err, req, res, next) => {
  res.locals.message = err.message;
  res.locals.error = process.env.NODE_ENV !== "production" ? err : {};
  res.status(err.status || 500);
  res.render("error");
});

app.listen(app.get("port"), () => {
  console.log(app.get("port"), "server is running 🚀");
});

app.use(passport.initialize())
req 객체에 passport 설정을 심는다.

app.use(passport.session())
req.session 객체에 passport 정보를 저장한다.

두개의 메서드는 session 미들웨어보다 아래쪽에 위치해야한다

이제 사용할 준비는 마쳤다 passport 설정을 진행해주자

const passport = require("passport");
const local = require("./localStrategy"); // 로그인 전략

const User = require("../models/user");

module.exports = () => {
  // 로그인시에만 실행 serializeUser
  passport.serializeUser
((user, done) => {
    done(null, user.id);
  });

  // 매 요청마다 실행 deserializeUser
  passport.deserializeUser((id, done) => {
    User.findOne({ where: { id } })
      .then((user) => done(null, user))
      .catch((err) => done(err));
  });

  local();
};

serializeUser 는 로그인시 실행되는 메서드

deserializeUser 는 매 요청마다 실행되는 메서드

serializeUser 에서는 user 정보를 받아서 deserializeUser 의 첫번째 인자로 넘겨준다 user 정보를 어디서 받아오는지는 뒤에 나온다.

done(에러, 데이터, 에러시 사용자 정의메세지)

passport.serializeUser 는 session 에 사용자 id를 저장하는 것이고

passport.desserializeUser 는 저장된 id로 사용자 정보를 가져오는 것이다

사용자 정보에 불필요한 정보 들이 들어가는것을 방지하는 목적

미들웨어 사용하기

로그인 상태에서는 로그인,회원가입 페이지 접근이 불가해야한다
로그아웃 상태에서는 마이페이지 같은 개인정보 페이지 접근이 불가능해야한다.

이러한 것을 미들웨어를 사용하여 처리를 할것인데 passport 객체가 req객체에 추가해주는 isAuthenticated 메서드를 사용하면 간편하게 구현이 가능하다

exports.isLoggedIn = (req, res, next) => {
 if (req.isAuthenticated()) {
   next();
 } else {
   res.status(403).send("로그인 필요");
 }
};

exports.isNotLoggedIn = (req, res, next) => {
 if (!req.isAuthenticated()) {
   next();
 } else {
   const message = encodeURIComponent("로그인한 상태입니다.");
   res.redirect(`/?error=${message}`);
 }
};

페이지 접근전에 해당 미들웨어를 추가해주면 된다.

profile
웹 & 앱개발 기록

0개의 댓글