From 75ca762c9d883483e4fd7ae0a5f7ec0dfa3d6b37 Mon Sep 17 00:00:00 2001 From: mic050r <103114387+mic050r@users.noreply.github.com> Date: Tue, 12 Dec 2023 13:46:14 +0900 Subject: [PATCH] =?UTF-8?q?feat=20:=20=EC=B9=B4=EC=B9=B4=EC=98=A4=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20api=20=EB=9D=BC=EC=9A=B0=ED=84=B0?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api.js | 122 +------------------------- public/addposit-it(wronganswer).html | 2 +- public/addpost-it(concept).html | 2 +- public/addpost-it(quiz).html | 2 +- public/category(concept).html | 2 +- public/category(quiz).html | 2 +- public/category(wronganswer).html | 2 +- public/home.html | 4 +- public/notibeboardtyping.html | 2 +- routes/auth.js | 123 +++++++++++++++++++++++++++ 10 files changed, 134 insertions(+), 129 deletions(-) create mode 100644 routes/auth.js diff --git a/api.js b/api.js index 243c5bc..ab35b87 100644 --- a/api.js +++ b/api.js @@ -1,21 +1,16 @@ // 모듈 선언 const express = require("express"); -const session = require("express-session"); const cors = require("cors"); const app = express(); const port = 3000; -const path = require("path"); const nunjucks = require("nunjucks"); -const axios = require("axios"); -const pool = require("./db/conn"); // 데이터베이스 연결 모듈 가져오기 -const qs = require("qs"); -const passport = require("passport"); const bodyParser = require("body-parser"); const inquiriesRouter = require("./routes/inquiries"); // 문의 사항 const conceptRouter = require("./routes/concept"); // 개념 포스트잇 const quizRouter = require("./routes/quiz"); // 퀴즈 포스트잇 const worngRouter = require("./routes/wrong"); // 퀴즈 포스트잇 +const authRouter = require("./routes/auth"); // 퀴즈 포스트잇 // 기본 설정 app.use(cors()); @@ -29,6 +24,7 @@ app.use("/inquiries", inquiriesRouter); // 문의사항 라우터 app.use("/concept", conceptRouter); // 개념 포스트잇 라우터 app.use("/quiz", quizRouter); // 개념 포스트잇 라우터 app.use("/wrong", worngRouter); // 개념 포스트잇 라우터 +app.use("/auth", authRouter); // 개념 포스트잇 라우터 app.use( express.static("public", { @@ -44,34 +40,6 @@ nunjucks.configure("views", { express: app, }); -app.use( - require("express-session")({ - secret: "ras", - resave: true, - saveUninitialized: true, - }) -); - -// Express 세션 설정 -app.use( - session({ - secret: "ras", - resave: true, - saveUninitialized: false, - }) -); - -passport.serializeUser((user, done) => { - done(null, user.id); -}); - -// Serialize 및 Deserialize 설정 -passport.deserializeUser((id, done) => { - User.findById(id, (err, user) => { - done(err, user); - }); -}); - // html 파일들 라우트 정의 app.get("/", (req, res) => { res.render("index"); @@ -79,92 +47,6 @@ app.get("/", (req, res) => { app.use(bodyParser.json()); app.use(express.urlencoded({ extended: true })); -// 카카오 API 정보 -const kakao = { - clientID: "2c536552403975785e3fdc6053dfb673", - clientSecret: "BHcC3tbvBXLAMDPfOav74BDmhIZFTe1s", - redirectUri: "http://localhost:3000/auth/kakao/callback", - logout_url: "http://localhost:3000/kakao/logout", -}; - -// http://localhost:3000/auth/kakao -app.get("/auth/kakao", (req, res) => { - const kakaoAuthURL = `https://kauth.kakao.com/oauth/authorize?client_id=${kakao.clientID}&redirect_uri=${kakao.redirectUri}&response_type=code`; - res.redirect(kakaoAuthURL); -}); -app.get("/auth/kakao/callback", async (req, res) => { - try { - const tokenResponse = await axios({ - method: "POST", - url: "https://kauth.kakao.com/oauth/token", - headers: { - "Content-Type": "application/x-www-form-urlencoded", - }, - data: qs.stringify({ - grant_type: "authorization_code", - client_id: kakao.clientID, - client_secret: kakao.clientSecret, - redirectUri: kakao.redirectUri, - code: req.query.code, - }), - }); - - const { access_token } = tokenResponse.data; - - const userResponse = await axios({ - method: "get", - url: "https://kapi.kakao.com/v2/user/me", - headers: { - Authorization: `Bearer ${access_token}`, - }, - }); - - // 사용자 정보를 세션에 저장 - req.session.kakao = userResponse.data; - - // 여기에서 세션에 토큰 및 사용자 정보 저장 - req.session.accessToken = access_token; - req.session.nickname = userResponse.data.properties.nickname; // 닉네임 - req.session.profileImage = userResponse.data.properties.profile_image; // 프로필 이미지 - - res.redirect("http://localhost:3000/home.html"); - } catch (error) { - console.error("Error:", error); - res.json(error.data); - } -}); - -app.get("/token", (req, res) => { - const tokenInfo = { - token: req.session.nickname, - }; - res.json(tokenInfo); -}); - -// 사용자 프로필, 닉네임 가져오는 API -app.get("/get-user-info", (req, res) => { - const userInfo = { - profileImage: req.session.profileImage, - nickname: req.session.nickname, - }; - - res.json(userInfo); -}); - -// Express 라우트에서 템플릿 렌더링 -app.get("/auth/info", (req, res) => { - const { nickname, profileImage } = req.session.kakao; - res.render("info", { - nickname, - profileImage, - }); -}); - -// 카카오 로그아웃 -> 카카오 로그아웃에 url 추가해야함 -app.get("/kakao/logout", async (req, res) => { - const kakaoAuthURL = `https://kauth.kakao.com/oauth/logout?client_id=${kakao.clientID}&logout_redirect_uri=${kakao.logout_url}`; - res.redirect(kakaoAuthURL); -}); app.listen(port, () => { console.log(`서버가 포트 ${port}에서 실행 중입니다.`); diff --git a/public/addposit-it(wronganswer).html b/public/addposit-it(wronganswer).html index 7c5df24..aab5efb 100644 --- a/public/addposit-it(wronganswer).html +++ b/public/addposit-it(wronganswer).html @@ -79,7 +79,7 @@ // 서버로부터 토큰을 가져오는 비동기 함수 async function getToken() { try { - const response = await fetch("http://localhost:3000/token"); + const response = await fetch("http://localhost:3000/auth/token"); if (!response.ok) { throw new Error("Network response was not ok"); } diff --git a/public/addpost-it(concept).html b/public/addpost-it(concept).html index b1f6f2b..0d3cac8 100644 --- a/public/addpost-it(concept).html +++ b/public/addpost-it(concept).html @@ -79,7 +79,7 @@ // 서버로부터 토큰을 가져오는 비동기 함수 async function getToken() { try { - const response = await fetch("http://localhost:3000/token"); + const response = await fetch("http://localhost:3000/auth/token"); if (!response.ok) { throw new Error("네트워크 응답이 올바르지 않습니다"); } diff --git a/public/addpost-it(quiz).html b/public/addpost-it(quiz).html index d8f5a79..6cd20be 100644 --- a/public/addpost-it(quiz).html +++ b/public/addpost-it(quiz).html @@ -86,7 +86,7 @@ // 서버로부터 토큰을 가져오는 비동기 함수 async function getToken() { try { - const response = await fetch("http://localhost:3000/token"); + const response = await fetch("http://localhost:3000/auth/token"); if (!response.ok) { throw new Error("네트워크 응답이 올바르지 않습니다"); } diff --git a/public/category(concept).html b/public/category(concept).html index 79d09a9..da3ad99 100644 --- a/public/category(concept).html +++ b/public/category(concept).html @@ -92,7 +92,7 @@ // 서버로부터 토큰을 가져오는 비동기 함수 async function getToken() { try { - const response = await fetch("http://localhost:3000/token"); + const response = await fetch("http://localhost:3000/auth/token"); if (!response.ok) { throw new Error("네트워크 응답이 올바르지 않습니다"); } diff --git a/public/category(quiz).html b/public/category(quiz).html index 5fb3954..7cc1bbf 100644 --- a/public/category(quiz).html +++ b/public/category(quiz).html @@ -99,7 +99,7 @@ // 서버로부터 토큰을 가져오는 비동기 함수 async function getToken() { try { - const response = await fetch("http://localhost:3000/token"); + const response = await fetch("http://localhost:3000/auth/token"); if (!response.ok) { throw new Error("네트워크 응답이 올바르지 않습니다"); } diff --git a/public/category(wronganswer).html b/public/category(wronganswer).html index 444082c..5ef21d7 100644 --- a/public/category(wronganswer).html +++ b/public/category(wronganswer).html @@ -92,7 +92,7 @@ // 서버로부터 토큰을 가져오는 비동기 함수 async function getToken() { try { - const response = await fetch("http://localhost:3000/token"); + const response = await fetch("http://localhost:3000/auth/token"); if (!response.ok) { throw new Error("네트워크 응답이 올바르지 않습니다"); } diff --git a/public/home.html b/public/home.html index 17ea570..f4ed5f2 100644 --- a/public/home.html +++ b/public/home.html @@ -85,7 +85,7 @@

포스트잇 추가

  • 문의사항
  • -
  • 로그아웃
  • +
  • 로그아웃
  • @@ -108,7 +108,7 @@

    포스트잇 추가

    // 예시로 fetch를 사용한 클라이언트 측 코드 async function getUserInfo() { try { - const response = await fetch("http://localhost:3000/get-user-info", { + const response = await fetch("http://localhost:3000/auth/user/info", { method: "GET", credentials: "include", }); diff --git a/public/notibeboardtyping.html b/public/notibeboardtyping.html index 934c353..b8c25d1 100644 --- a/public/notibeboardtyping.html +++ b/public/notibeboardtyping.html @@ -35,7 +35,7 @@

    게시글 작성

    // 비동기 함수 내에서 await 사용 async function getToken() { try { - const response = await fetch("http://localhost:3000/token"); + const response = await fetch("http://localhost:3000/auth/token"); if (!response.ok) { throw new Error("Network response was not ok"); } diff --git a/routes/auth.js b/routes/auth.js new file mode 100644 index 0000000..5512160 --- /dev/null +++ b/routes/auth.js @@ -0,0 +1,123 @@ +// 모듈 선언 +const qs = require("qs"); +const express = require("express"); +const session = require("express-session"); +const axios = require("axios"); +const passport = require("passport"); +const router = express.Router(); + +router.use( + require("express-session")({ + secret: "ras", + resave: true, + saveUninitialized: true, + }) +); + +// Express 세션 설정 +router.use( + session({ + secret: "ras", + resave: true, + saveUninitialized: false, + }) +); + +passport.serializeUser((user, done) => { + done(null, user.id); +}); + +// Serialize 및 Deserialize 설정 +passport.deserializeUser((id, done) => { + User.findById(id, (err, user) => { + done(err, user); + }); +}); + +// 카카오 API 정보 +const kakao = { + clientID: "2c536552403975785e3fdc6053dfb673", + clientSecret: "BHcC3tbvBXLAMDPfOav74BDmhIZFTe1s", + redirectUri: "http://localhost:3000/auth/kakao/callback", + logout_url: "http://localhost:3000/auth/kakao/logout", +}; + +// http://localhost:3000/auth/kakao +router.get("/kakao", (req, res) => { + const kakaoAuthURL = `https://kauth.kakao.com/oauth/authorize?client_id=${kakao.clientID}&redirect_uri=${kakao.redirectUri}&response_type=code`; + res.redirect(kakaoAuthURL); +}); + +router.get("/kakao/callback", async (req, res) => { + try { + const tokenResponse = await axios({ + method: "POST", + url: "https://kauth.kakao.com/oauth/token", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + data: qs.stringify({ + grant_type: "authorization_code", + client_id: kakao.clientID, + client_secret: kakao.clientSecret, + redirectUri: kakao.redirectUri, + code: req.query.code, + }), + }); + + const { access_token } = tokenResponse.data; + + const userResponse = await axios({ + method: "get", + url: "https://kapi.kakao.com/v2/user/me", + headers: { + Authorization: `Bearer ${access_token}`, + }, + }); + + // 사용자 정보를 세션에 저장 + req.session.kakao = userResponse.data; + + // 여기에서 세션에 토큰 및 사용자 정보 저장 + req.session.accessToken = access_token; + req.session.nickname = userResponse.data.properties.nickname; // 닉네임 + req.session.profileImage = userResponse.data.properties.profile_image; // 프로필 이미지 + + res.redirect("http://localhost:3000/home.html"); + } catch (error) { + console.error("Error:", error); + res.json(error.data); + } +}); + +router.get("/token", (req, res) => { + const tokenInfo = { + token: req.session.nickname, + }; + res.json(tokenInfo); +}); + +// 사용자 프로필, 닉네임 가져오는 API +router.get("/user/info", (req, res) => { + const userInfo = { + profileImage: req.session.profileImage, + nickname: req.session.nickname, + }; + + res.json(userInfo); +}); + +router.get("/kakao/logout", async (req, res) => { + // 세션 초기화 + req.session.destroy((err) => { + if (err) { + console.error("세션 초기화 오류:", err); + } + + // 카카오 로그아웃 URL로 리다이렉트 + const kakaoAuthURL = `https://kauth.kakao.com/oauth/logout?client_id=${kakao.clientID}&logout_redirect_uri=${kakao.logout_url}`; + res.redirect(kakaoAuthURL); + }); +}); + +module.exports = router;