Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ app.get("/", (req, res) => {
res.send("🚀 Server is running!");
});


// ✅ API 라우트 설정 (⚡ 충돌 방지: `/api` 경로를 일관되게 유지)
app.use("/api", userRoutes); // 사용자 관리 API
app.use("/api/bottle", bottleMessageRoutes); // 유리병 편지 관련 API
Expand All @@ -68,4 +69,5 @@ app.use((req, res, next) => {
// ✅ 서버 실행
app.listen(PORT, '0.0.0.0', () => {
console.log(`🚀 Server is running on port ${PORT}`);
});
});

98 changes: 89 additions & 9 deletions controllers/authController.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,102 @@
// import dotenv from 'dotenv';
// import { google } from 'googleapis';
// import fs from 'fs';

// dotenv.config();

// // Google OAuth 2.0 클라이언트 생성
// const oAuth2Client = new google.auth.OAuth2(
// process.env.GOOGLE_CLIENT_ID,
// process.env.GOOGLE_CLIENT_SECRET,
// process.env.GOOGLE_REDIRECT_URI
// );

// // Google 로그인 URL 생성 (프론트엔드에서 요청 시 로그인 url을 반환하는 방식으로 수정 가능)
// export const getAuthURL = (req, res) => {
// try {
// const authUrl = oAuth2Client.generateAuthUrl({
// access_type: 'offline', // refresh_token을 받기 위해 'offline' 설정
// scope: ['https://www.googleapis.com/auth/drive.file'],
// prompt: 'consent', // 항상 refresh_token을 받을 수 있도록 설정
// });

// console.log("Generated Auth URL:", authUrl);
// // res.json({ authUrl }); // 프론트엔드에 로그인 URL 반환 방식
// res.redirect(authUrl); // Google 로그인 화면으로 자동 이동 방식
// } catch (error) {
// console.error("Error generating auth URL:", error);
// res.status(500).json({ error: 'Failed to generate authentication URL' });
// }
// };

// // Google OAuth 콜백 처리 (토큰 저장)
// export const handleOAuthCallback = async (req, res) => {
// try {
// const { code } = req.query;
// if (!code) return res.status(400).json({ error: 'Authorization code is missing' });

// // 인증 코드로 Access Token & Refresh Token 요청
// const { tokens } = await oAuth2Client.getToken(code);
// oAuth2Client.setCredentials(tokens);

// console.log("Received Tokens:", tokens);

// // refresh_token 저장 (자동으로 .env의 GOOGLE_REFRESH_TOKEN 필드 업데이트)
// if (tokens.refresh_token) {
// const envFilePath = '.env';
// let envData = fs.readFileSync(envFilePath, 'utf8');

// // 기존 GOOGLE_REFRESH_TOKEN이 있으면 업데이트, 없으면 추가
// if (envData.includes('GOOGLE_REFRESH_TOKEN=')) {
// envData = envData.replace(/^GOOGLE_REFRESH_TOKEN=.*$/m, `GOOGLE_REFRESH_TOKEN=${tokens.refresh_token}`);
// } else {
// envData += `\nGOOGLE_REFRESH_TOKEN=${tokens.refresh_token}\n`;
// }

// fs.writeFileSync(envFilePath, envData, 'utf8');
// console.log("Refresh Token saved to .env");
// }

// // Access Token을 프론트엔드에 반환
// res.json({
// message: "Authorization successful",
// accessToken: tokens.access_token,
// refreshToken: tokens.refresh_token || "No new refresh token received",
// expiresIn: tokens.expiry_date,
// });

// } catch (error) {
// console.error("OAuth Callback Error:", error);
// res.status(500).json({ error: "Authorization failed", details: error.message });
// }
// };

import dotenv from 'dotenv';
import { google } from 'googleapis';
import fs from 'fs';

dotenv.config();

let accessToken = null; // Access Token 저장 변수

// Google OAuth 2.0 클라이언트 생성
const oAuth2Client = new google.auth.OAuth2(
process.env.GOOGLE_CLIENT_ID,
process.env.GOOGLE_CLIENT_SECRET,
process.env.GOOGLE_REDIRECT_URI
);

// Google 로그인 URL 생성 (프론트엔드에서 요청 시 로그인 url을 반환하는 방식으로 수정 가능)
// Google 로그인 URL 생성
export const getAuthURL = (req, res) => {
try {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline', // refresh_token을 받기 위해 'offline' 설정
access_type: 'offline',
scope: ['https://www.googleapis.com/auth/drive.file'],
prompt: 'consent', // 항상 refresh_token을 받을 수 있도록 설정
prompt: 'consent',
});

console.log("Generated Auth URL:", authUrl);
// res.json({ authUrl }); // 프론트엔드에 로그인 URL 반환 방식
res.redirect(authUrl); // Google 로그인 화면으로 자동 이동 방식
res.redirect(authUrl);
} catch (error) {
console.error("Error generating auth URL:", error);
res.status(500).json({ error: 'Failed to generate authentication URL' });
Expand All @@ -35,18 +109,17 @@ export const handleOAuthCallback = async (req, res) => {
const { code } = req.query;
if (!code) return res.status(400).json({ error: 'Authorization code is missing' });

// 인증 코드로 Access Token & Refresh Token 요청
const { tokens } = await oAuth2Client.getToken(code);
oAuth2Client.setCredentials(tokens);

accessToken = tokens.access_token; // Access Token 저장

console.log("Received Tokens:", tokens);

// refresh_token 저장 (자동으로 .env의 GOOGLE_REFRESH_TOKEN 필드 업데이트)
if (tokens.refresh_token) {
const envFilePath = '.env';
let envData = fs.readFileSync(envFilePath, 'utf8');

// 기존 GOOGLE_REFRESH_TOKEN이 있으면 업데이트, 없으면 추가
if (envData.includes('GOOGLE_REFRESH_TOKEN=')) {
envData = envData.replace(/^GOOGLE_REFRESH_TOKEN=.*$/m, `GOOGLE_REFRESH_TOKEN=${tokens.refresh_token}`);
} else {
Expand All @@ -57,7 +130,6 @@ export const handleOAuthCallback = async (req, res) => {
console.log("Refresh Token saved to .env");
}

// Access Token을 프론트엔드에 반환
res.json({
message: "Authorization successful",
accessToken: tokens.access_token,
Expand All @@ -70,3 +142,11 @@ export const handleOAuthCallback = async (req, res) => {
res.status(500).json({ error: "Authorization failed", details: error.message });
}
};

// 저장된 Access Token 반환
export const getAccessToken = (req, res) => {
if (!accessToken) {
return res.status(400).json({ error: "No access token available. Please authenticate first." });
}
res.json({ accessToken });
};
3 changes: 1 addition & 2 deletions models/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@ export const db = mysql.createPool({
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
});

});
22 changes: 18 additions & 4 deletions routes/authRoutes.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
import { getAuthURL, handleOAuthCallback } from "../controllers/authController.js";
// import { getAuthURL, handleOAuthCallback } from "../controllers/authController.js";
// import express from "express";

// const authRoutes = express.Router();

// // Google 로그인 URL 생성
// authRoutes.get("/", getAuthURL);

// // Google OAuth 로그인 성공 후 콜백
// authRoutes.get("/callback", handleOAuthCallback);

// // 프론트에서 OAuth 인증 후 받은 code를 백엔드에 전달하는 엔드포인트
// authRoutes.get("/token");

// export default authRoutes;

import { getAuthURL, handleOAuthCallback, getAccessToken } from "../controllers/authController.js";
import express from "express";

const authRoutes = express.Router();

// Google 로그인 URL 생성
authRoutes.get("/", getAuthURL);

// Google OAuth 로그인 성공 후 콜백
authRoutes.get("/callback", handleOAuthCallback);
authRoutes.get("/token", getAccessToken); // 새 함수 추가

export default authRoutes;