https://yeon960.tistory.com/271
이전편(프로젝트 세팅)은 요기👆
Passport 모듈로 로그인 구현하기
1. passport관련 패키지 설치
$npm i passport passport-local passport-kakao bcrypt
2. app.js와 연결
//app.js
...
const flash = require('connect-flash');
const passport = require('passport'); // 추가1-passport모듈과 연결
require('dotenv').config(); // 비밀키 불러오기
const pageRouter = require('./routes/page'); // 라우터 가져오기
const { sequelize } = require('./models'); // 모델 서버 연결
const passportConfig = require('./passport'); // 추가2-passport모듈과 연결
...
const app = express();
sequelize.sync(); // 모델 서버 연결
passportConfig(passport); // 추가3-passport모듈과 연결
...
app.use(flash());
app.use(passport.initialize()); // 추가4-요청(req)에 passport설정 심어줌
app.use(passport.session()); // 추가5-req.session객체에 passport정보를 저장
3. 모듈 작성
app.js와 연결했던 Passport 모듈 작성
// passport.index.js
const local = require('./localStrategy');
const kakao = require('./kakaoStrategy');
const { User } = require('../models');
module.exports = (passport) => {
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(passport);
kakao(passport);
};
4. 로컬 로그인 구현
1) middlewares.js 추가
// routes/middlewares.js
exports.isLoggedIn = (req, res, next) => {
if (req.isAuthenticated()) {
next();
} else {
res.status(403).send('로그인 필요');
}
};
exports.isNotLoggedIn = (req, res, next) => {
if (!req.isAuthenticated()) {
next();
} else {
res.redirect('/');
}
};
2) page.js 수정
// routes/page.js
const express = require('express');
const { isLoggedIn, isNotLoggedIn } = require('./middlewares'); // 추가1
const router = express.Router();
// http://localhost:8001/profile
router.get('/profile', (req, res) => {
res.render('profile', { title: '내 정보 - NodeInsta', user: req.user }); // 추가2
});
// http://localhost:8001/join
router.get('/join', (req, res) => {
res.render('join', {
title: '회원가입 - NodeInsta',
user: req.user, // 추가3
joinError: req.flash('joinError'),
});
});
// http://localhost:8001/
router.get('/', (req, res, next) => {
res.render('main', {
title: 'NodeBird',
twits: [],
user: req.user, // 추가4
loginError: req.flash('loginError'),
});
});
module.exports = router;
3) auth.js 추가
// routes/auth.js
const express = require('express');
const passport = require('passport');
const bcrypt = require('bcrypt');
const { isLoggedIn, isNotLoggedIn } = require('./middlewares');
const { User } = require('../models');
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) {
req.flash('joinError', '이미 가입된 이메일입니다.');
return res.redirect('/join');
}
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) {
req.flash('loginError', info.message);
return res.redirect('/');
}
return req.login(user, (loginError) => {
if (loginError) {
console.error(loginError);
return next(loginError);
}
return res.redirect('/');
});
})(req, res, next); // 미들웨어 내의 미들웨어에는 (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;
4) localStrategy.js
// passport/localStrategy.js
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcrypt');
const { User } = require('../models');
module.exports = (passport) => {
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);
}
}));
};
5. 카카오 로그인 구현
1) kakaoStrategy.js 추가
// passport/kakaoStrategy.js
const KakaoStrategy = require('passport-kakao').Strategy;
const { User } = require('../models');
module.exports = (passport) => {
passport.use(new KakaoStrategy({
clientID: process.env.KAKAO_ID,
callbackURL: '/auth/kakao/callback',
}, async (accessToken, refreshToken, profile, done) => {
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.kaccount_email,
nick: profile.displayName,
snsId: profile.id,
provider: 'kakao',
});
done(null, newUser);
}
} catch (error) {
console.error(error);
done(error);
}
}));
};
2) auths.js 수정
// routes/auth.js
...
/* 추가 시작 */
router.get('/kakao', passport.authenticate('kakao'));
router.get('/kakao/callback', passport.authenticate('kakao', {
failureRedirect: '/',
}), (req, res) => {
res.redirect('/');
});
/* 추가 끝 */
module.exports = router;
3) app.js 수정
// app.js
...
const pageRouter = require('./routes/page'); // 라우터 가져오기
const authRouter = require('./routes/auth');
...
app.use('/', pageRouter);
app.use('/auth', authRouter);
...
4) clientID 발급
kakaoStrategy.js의 clientID 부분을 발급받는다.
카카오 로그인을 위해 카카오 개발자 계정과 카카오용 앱이 필요하다.
https://developers.kakao.com 에 접속하여 회원가입 후 아래의 절차에 따라보자.
카카오용 nodeInsta 앱을 만든다.
앱 생성 후 REST API키를 복사하여 .env 파일에 넣어준다.
5) .env 수정
// .env
COOKIE_SECRET=nodeInstasecret
KAKAO_ID= //rest api 값
6) 내 애플리케이션>앱 설정>플랫폼>web 플랫폼 등록
http://localhost:8001 입력
7) Redirect URI를 등록
등록된 사이트 도메인 밑에 등록하러 가기 url 클릭.
8) redirect URL 추가
http://localhost:8001/auth/kakao/callback
9) redirect URL 추가하는 곳 바로 위에 활성화 설정에 활성화 on으로
6. 서버실행
$npm start
http://localhost:8001/에 접속하여 카카오 로그인 확인
7. 확인하기
아래와 같이 카카오 로그인이나 회원가입이 뜨면 성공~~
다음편(이미지 업로드 구현)은 요기👇
https://yeon960.tistory.com/274
'개인공부 > Node.js' 카테고리의 다른 글
nodejs로 SNS 만들기 #4 (1) | 2022.08.15 |
---|---|
User.find is not a function 오류 발생 시 해결 방법 (0) | 2022.08.15 |
nodejs로 SNS 만들기 #2 (0) | 2022.08.09 |
nodejs로 SNS 만들기 #1 (0) | 2022.08.09 |
[터미널 설정 문제] 'node' 용어가 cmdlet, 함수, 스크립트 파일 또는 실행할 수 있는 프로그램 이름으로 인식되지 않습니다. (0) | 2022.07.21 |