Passport는 클라이언트의 요청을 authenticate 해주는 미들웨어이다.
passport.js 패키지를 사용하여 패스워드 암호화한다.
이전 게시글의 기본 설정을 유지한다.
$ npm install passport
$ npm install passport-local-mongoose
mongoose를 사용하고 있기 때문에 passport-local-mongoose를 설치한다.
require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const ejs = require('ejs');
const mongoose = require('mongoose');
const passport = require('passport');
const passportLocalMongoose = require('passport-local-mongoose');
const userSchema = new mongoose.Schema({
email: String,
password: String,
});
// mongoose API의 Schema는 플러그인을 추가할 수 있다.
userSchema.plugin(passportLocalMongoose);
Strategies는 요청에 대한 인증 매커니즘을 수행한다.
const User = mongoose.model('User', userSchema);
// 전략을 직접 구성하지 않고, createStrategy() 메서드를 이용하여 자동 생성한 후 등록
passport.use(User.createStrategy());
createStrategy()
: 미리 설정이 완료된 passport-local LocalStrategy 인스턴스를 생성한다.app.post('/register', (req, res) => {
// req에서 전달받은 username과 password를 사용하여 유저 객체를 DB에 등록한다.
User.register(
{ username: req.body.username },
req.body.password,
function (err, user) {
if (err) {
console.log(err);
} else {
// 이미 존재하는 유저일 경우 인증요청
// 아이디와 패스워드가 일치하면 시크릿 페이지로
passport.authenticate('local')(req, res, function () {
res.redirect('/secrets');
});
}
}
);
});
app.post('/login', (req, res) => {
const user = new User({
username: req.body.username,
password: req.body.password,
});
req.login(user, function (err) {
if (err) {
console.log(err);
} else {
// 'local' 전략 사용, 함수 반환
passport.authenticate('local')(req, res, function () {
res.redirect('/secrets');
});
}
});
});
createStrategy > passport.use(LocalStrategy) > authenticate
로그인 후 로그아웃 구현을 위해 세션 사용
세션 등록하는 위치 중요!
npm i express-session
const session = require('express-session');
app.use(express.static('public'));
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: true }));
// 세션 등록
app.use(
session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
})
);
// passport 초기화
app.use(passport.initialize());
// passport 초기화 후 세션 등록
app.use(passport.session());
// ...
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
isAuthenticated()
클라이언트가 보낸 req에 세션이 유지되어 있는지 확인하고 인증된 상태라면 바로 비밀페이지로 이동가능하다.
세션이 끊겼으면 비밀페이지를 요청하더라도 로그인 페이지로 이동한다.
app.get('/secrets', (req, res) => {
if (req.isAuthenticated()) {
res.render('secrets');
} else {
res.redirect('/login');
}
});
logOut()
메서드로 간단하게 구현가능하다. 세션을 종료하고 메인 페이지로 돌아간다.
app.get('/logout', function (req, res) {
req.logOut();
res.redirect('/');
});