passport 모듈을 사용하여 세션로그인 구현해보기
express-session 을 미들웨어로 사용하면 세션객체를 받을 수 있다
확인방법은 req.session
app.use(
session({
resave: false,
saveUninitialized: false,
secret: process.env.COOKIE_SECRET,
cookie: {
httpOnly: true,
secure: false,
},
})
);
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}`);
}
};
페이지 접근전에 해당 미들웨어를 추가해주면 된다.