passport 모듈로 passport설정 및 실행파일 export
const passport = require('passport');
const local = require('./localStrategy');
const kakao = require('./kakaoStrategy');
const User = require('../models/user');
module.exports = () => {
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findOne({ where: { id } })
.then(user => done(null, user))
.catch(err => done(err));
});
local();
kakao();
};
middleware를 통해 로그인 여부를 판단하여 각 페이지에 제한을 둔다.
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}`);
}
};
page라우터에서 post join요청일 경우 회원가입 전략 post login일 경우 local 로그인 전략을 실행한다. get kakao일 경우 kakao전략 실행
const express = require('express');
const passport = require('passport');
const bcrypt = require('bcrypt');
const { isLoggedIn, isNotLoggedIn } = require('./middlewares');
const User = require('../models/user');
const router = express.Router();
router.post('/join', isNotLoggedIn, async (req, res, next) => {
const { email, nick, password } = req.body;
try {
const exUser = await User.findOne({ where : { email } });
if(exUser){
return res.redirect('/join?error=exist');
}
const hash = await bcrypt.hash(password, 12);
await User.create({
email,
nick,
password: hash,
});
return res.redirect('/');
}catch(error){
console.error(error);
return next(error);
}
});
router.post('/login', isNotLoggedIn, (req, res, next) => {
passport.authenticate('local', (authError, user, info) => {
if(authError){
console.error(authError);
return next(authError);
}
if(!user){
return res.redirect(`/?loginError=${info.message}`);
}
return req.login(user, (loginError) => {
if(loginError){
console.error(loginError);
return next(loginError);
}
return res.redirect('/');
});
})(req,res,next);
});
router.get('/logout', isLoggedIn, (req, res) => {
req.logout();
req.session.destroy();
res.redirect('/');
});
router.get('/kakao', passport.authenticate('kakao'));
router.get('/kakao/callback', passport.authenticate('kakao', {
failureRedirect: '/',
}), (req,res) => {
res.redirect('/');
});
module.exports = router;
로그인 결과를 callback함수로 auth페이지에 전달
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcrypt');
const User = require('../models/user');
module.exports = () => {
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
}, async (email, password, done) => {
try {
const exUser = await User.findOne({ where: { email } });
if(exUser){
const result = await bcrypt.compare(password, exUser.password);
if(result) {
done(null, exUser);
}else{
done(null, false, { message: '비밀번호가 일치하지 않습니다.' });
}
}else{
done(null, false, { message: '가입되지 않은 회원입니다.' });
}
} catch (error){
console.error(error);
done(error);
}
}));
};
KAKAO 페이지와 연동한 키를 사용하여, 회원이 아닐 경우 회원정보를 전달받아 insert 회원일 경우 로그인 전략 실행 후 callback함수 실행
const passport = require('passport');
const KakaoStrategy = require('passport-kakao').Strategy;
const User = require('../models/user');
module.exports = () => {
passport.use(new KakaoStrategy({
clientID: process.env.KAKAO_ID,
callbackURL:'/auth/kakao/callback',
}, async (accessToken, refreshToken, profile, done) => {
console.log('kakao profile', profile);
try {
const exUser = await User.findOne({
where: { snsId:profile.id, provider: 'kakao' },
});
if(exUser){
done(null, exUser);
}else{
const newUser = await User.create({
email:profile._json && profile._json.kakao_account_email,
nick: profile.displayName,
snsId: profile.id,
profider: 'kakao',
});
done(null, newUser);
}
}catch(error){
console.error(error);
done(error);
}
}));
}