01. 준비하기
- kakao developer 가입하기
- 현재 작업하고 있는 프로젝트에 모듈 설치 (passport, passport-kakao, jwtwebtoken)
npm install passport passport-kakao jwtwebtoken
02. 시작하기
- kakao developer 설정
1. 내 애플리케이션 생성
2. 앱 아이콘은 처음부터 등록하기를 추천 (후에 동의 항목을 설정할 때 필요), 앱 이름, 사업자명, 서비스 이용 제한 체크 후에 저장
3. 생성된 앱을 클릭 ㅡ> 비즈니스 ㅡ> 개인 개발자 비즈 앱 전환 ㅡ> 이메일 필수 동의 ㅡ> 전환
==> 동의 항목에서 이메일을 가져올 때 필요하다.
4. 제품 설정 ㅡ> 카카오 로그인 ㅡ> 동의 항목 : 원하는 항목을 설정에서 체크하기
5. 제품 설명 ㅡ> 카카오 로그인 ㅡ> Redirection URI 설정 추가하기 (이 부분은 후에 프론트 엔드와 같이 설정할 때 수정해야 한다.)
- node.js 설정
1. 프로젝트에 passport 폴더 생성 ㅡ> kakaStrategy.js 생성
- kakaoStrategy.js
const passport = require("passport");
const KakaoStrategy = require("passport-kakao").Strategy;
const jwt = require("jsonwebtoken");
const { Users } = require("../models");
module.exports = () => {
passport.use(
new KakaoStrategy(
{
clientID: process.env.KAKAO_ID,
callbackURL: "/auth/kakao/callback",
},
async (accessToken, refreshToken, profile, done) => {
try {
const exUser = await Users.findOne({
where: {
email: profile._json.kakao_account.email,
},
});
// 기존 사용자일 경우
if (exUser) {
const token = jwt.sign(
{
userId: exUser.userId,
},
process.env.JWT_SECRET
);
return done(null, token);
} else {
// 새로운 사용자일 경우
const newUser = await Users.create({
email: profile._json.kakao_account.email,
nickName: profile.displayName,
});
const token = jwt.sign(
{
userId: newUser.userId,
},
process.env.JWT_SECRET
);
console.log(token);
return done(null, token);
}
} catch (error) {
console.error(error);
done(error);
}
}
)
);
};
==> 카카오에서 제공해주는 토큰을 이용하지 않고 새로운 JWT 토큰을 생성해서 사용할 계획이다. 따라서 토큰을 생성하는 부분을 꼭 넣어줘야 한다.
2. routes 폴더 ㅡ> auth.js 생성
- auth.js
const express = require("express");
const router = express.Router();
const passport = require("passport");
//* 카카오로 로그인하기 라우터 ***********************
//? /kakao로 요청오면, 카카오 로그인 페이지로 가게 되고, 카카오 서버를 통해 카카오 로그인을 하게 되면, 다음 라우터로 요청한다.
router.get("/auth/kakao", passport.authenticate("kakao"));
//? 위에서 카카오 서버 로그인이 되면, 카카오 redirect url 설정에 따라 이쪽 라우터로 오게 된다.
router.get(
"/auth/kakao/callback",
//? 그리고 passport 로그인 전략에 의해 kakaoStrategy로 가서 카카오계정 정보와 DB를 비교해서 회원가입시키거나 로그인 처리하게 한다.
passport.authenticate("kakao", {
failureRedirect: "/", // kakaoStrategy에서 실패한다면 실행
}),
// kakaoStrategy에서 성공한다면 콜백 실행
(req, res) => {
const token = req.user; // 사용자 토큰 정보 (예: JWT 토큰)
const query = "?token=" + token;
res.locals.token = token;
res.redirect(`http://localhost:3000/${query}`);
}
);
router.get("/auth/logout", (req, res) => {
req.logout(function (err) {
if (err) {
console.error(err);
return res.redirect("/"); // 로그아웃 중 에러가 발생한 경우에 대한 처리
}
res.redirect("http://localhost:3000/"); // 로그아웃 성공 시 리다이렉트
});
});
module.exports = router;
==> 현재 작업은 HTTP에서 구현하는 방법이기에 쿠키로 넣는 방식이 아니라 localstorage에 넣는 방법을 선택했다.
(후에 HTTPS로 바꿔서 프로젝트를 마무리 할 것이다. 그때 글을 다시 수정할 계획)
3. app.js 수정
// import
const express = require("express");
const kakao = require("./passport/kakaoStrategy");
const passport = require("passport");
const path = require("path");
require("dotenv").config();
// router
const authRouter = require("./routes/auth");
const boatRouter = require("./routes/boats");
const commentRouter = require("./routes/comments");
const alarmRouter = require("./routes/alarms");
const userRouter = require("./routes/users");
// 설정
const cookieParser = require("cookie-parser");
const session = require("express-session");
const cors = require("cors");
const app = express();
app.use(
cors({
origin: [
"http://localhost:3000",
],
credentials: true,
})
);
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));
app.use(
session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
domain: " ", // 프론트엔드와 연결한 도메인으로 설정하면 모든 서브도메인에서 쿠키를 사용할 수 있습니다.
path: "/", // /로 설정하면 모든 페이지에서 쿠키를 사용할 수 있습니다.
secure: false, // https가 아닌 환경에서도 사용할 수 있습니다.
httpOnly: false, // 자바스크립트에서 쿠키를 확인할 수 있습니다.
},
})
);
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser((token, done) => {
done(null, token);
});
passport.deserializeUser((token, done) => {
// 토큰을 이용하여 사용자를 인증 또는 사용자 정보를 가져오는 로직 구현
// 예시: 토큰에서 userId를 추출하여 사용자 정보를 가져옴
const decoded = jwt.verify(token, process.env.JWT_SECRET);
const userId = decoded.userId;
Users.findByPk(userId)
.then((user) => {
done(null, user); // 사용자 객체를 세션에서 가져옴
})
.catch((err) => {
done(err);
});
});
kakao(); // kakaoStrategy.js의 module.exports를 실행합니다.
app.use("/", [boatRouter, authRouter, commentRouter, alarmRouter, userRouter]);
const PORT = 3000;
app.listen(PORT, () => {
console.log(PORT, "포트 번호로 서버가 실행되었습니다.");
});
==> 주석처리한 내용을 잘 확인하기
4. .env 파일 생성
SESSION_SECRET=your_secret_string
KAKAO_ID=REST API 키 가져오기
JWT_SECRET=JWT 토큰 암호
==> 카카오에서 가져오는 방법
내 애플리케이션 ㅡ> 앱 키 ㅡ> REST API 키 복사 ㅡ> 환경 변수에 넣어주기
03. 프론트 엔드 설정
- React 설정
==> 로그인 파일
import React from 'react';
import KakaoBtn from './kakao_login_medium_narrow.png';
function Kakaologin() {
const loginUrl = `${process.env.REACT_APP_BACKEND_SERVER_URL}/auth/kakao`;
return (
<div>
<a href={loginUrl}>
<img src={KakaoBtn} alt='kakao login button' />
</a>
</div>
);
}
export default Kakaologin;
==> .env 파일 (환경 변수 설정)에 백엔드 서버를 넣어주면 된다. 임시 방편으로 현재는 localstorage에 토큰을 넣는 방식이므로 후에 수정할 계획이다.)
'JavaScript Dev. > Node.js' 카테고리의 다른 글
JWT 토큰 보안을 강화하기.... (0) | 2023.07.21 |
---|---|
node-cron란?? (feat. cron) (0) | 2023.06.21 |
AWS EC2를 이용해 HTTPS 배포 (feat. 가비아) (2) | 2023.06.02 |
Layered Architecture Pattern (0) | 2023.05.19 |
Access, Refresh Token?? (0) | 2023.05.08 |