diff --git a/app.js b/app.js index 14cb4e9cd8b32ac83120da6c4845ac2543cf0f60..1d39f3f5a89f600d58789ada5d990abbc01347e0 100644 --- a/app.js +++ b/app.js @@ -3,43 +3,22 @@ const app = express(); const mongoose = require('mongoose'); const cors = require('cors'); -//app.use(express.urlencoded({ extended: false })); +app.use(express.urlencoded({ extended: false })); const passport = require('./config/passport'); -//const cookieParser = require('cookie-parser'); -const cookieParser = require('cookie-parser'); -app.use(cookieParser()); + app.use(passport.initialize()); //const session = require('express-session'); const jwt = require('jsonwebtoken'); require('dotenv').config(); const secretKey = process.env.JWT_SECRET; // 실제 환경에서는 환경 변수로 관리하세요. -const refreshTokenSecretKey = process.env.JWT_REFRESH_SECRET; - -const https = require('https'); -const fs = require('fs'); -const expressSanitizer = require('express-sanitizer'); - -app.use(express.json()); -app.use(express.urlencoded({ extended: true })); -app.use(expressSanitizer()); -app.use('/', express.static('public')); - -// SSL 인증서와 개인 키 파일 경로 설정 -const sslOptions = { - key: fs.readFileSync('./cert/server.key'), - cert: fs.readFileSync('./cert/server.cert'), -}; - const http = require('http'); const WebSocketServer = require('./WebSocket'); //middleware app.use(cors({ - origin: "https://localhost:3000", - credentials: true, //쿠키전송 허용 - methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], - allowedHeaders: ['Content-Type', 'Authorization'] + origin: "http://localhost:3000", + credentials: true, })); //비밀번호 변경 라우트 등록 const passwordRoutes = require('./route/conf_password'); @@ -88,6 +67,14 @@ app.use('/del_user', authenticateToken, deleteUser); console.log('GOOGLE_CLIENT_ID:', process.env.GOOGLE_CLIENT_ID); console.log('GOOGLE_CLIENT_SECRET:', process.env.GOOGLE_CLIENT_SECRET); + +// // MongoDB 연결 +// mongoose.connect('mongodb://localhost:27017/logininfo', { +// useNewUrlParser: true, +// useUnifiedTopology: true, +// }).then(() => console.log('MongoDB 연결 성공')) +// .catch(err => console.error('MongoDB 연결 오류:', err)); + // application/x-www-form-urlencoded app.use(express.urlencoded({ extended: false })); @@ -121,7 +108,7 @@ app.get('/googlelogin', passport.authenticate('google', { scope: ['profile', 'email'], session: false }) ); -//세션 로그인 ------------------------------------- +//jwt 전-------------------------------------- // app.get('/googlelogin/redirect', // passport.authenticate('google', { failureRedirect: '/' }), // (req, res) => { @@ -141,109 +128,27 @@ app.get('/googlelogin', //jwt 후----------------------------------------- app.get('/googlelogin/redirect', passport.authenticate('google', { failureRedirect: '/', session: false }), - async (req, res) => { - const accessToken = jwt.sign( + (req, res) => { + const token = jwt.sign( { userId: req.user._id, email: req.user.email, name: req.user.name }, secretKey, - { expiresIn: '15m' } + { expiresIn: '1h' } ); - const refreshToken = jwt.sign( - { userId: req.user._id }, - refreshTokenSecretKey, - { expiresIn: '7d' } // 리프레시 토큰 유효 기간: 7일 - ); - - // 토큰 로그 출력 - console.log('생성된 액세스 토큰:', accessToken); - console.log('생성된 리프레시 토큰:', refreshToken); - - // 사용자 데이터베이스에 리프레시 토큰 저장 - req.user.refreshToken = refreshToken; - await req.user.save(); - - // 쿠키에 토큰 저장 - res.cookie('accessToken', accessToken, { - httpOnly: true, - secure: true, - sameSite: 'Strict', - maxAge: 15 * 60 * 1000 // 15분 - }); - - res.cookie('refreshToken', refreshToken, { - httpOnly: true, - secure: true, - sameSite: 'Strict', - maxAge: 7 * 24 * 60 * 60 * 1000 // 7일 - }); - res.redirect('https://localhost:3000/'); + res.redirect(`http://localhost:3000/login#token=${token}`); console.log(`구글 로그인 성공: ${req.user.email}`); } ); //------------------------------------------------- // 로그아웃 -app.get('/logout', async(req, res) => { +app.get('/logout', (req, res) => { // req.logout((err) => { // if (err) { return next(err); } // res.redirect('/'); // }); - //res.clearCookie('token'); //쿠키삭제 - const refreshToken = req.cookies.refreshToken; - - // 리프레시 토큰 무효화 - if (refreshToken) { - try { - const decoded = jwt.verify(refreshToken, refreshTokenSecretKey); - const user = await User.findById(decoded.userId); - if (user) { - user.refreshToken = null; - await user.save(); - } - } catch (err) { - console.error('리프레시 토큰 검증 오류:', err); - } - } - - // 쿠키 삭제 - res.clearCookie('accessToken'); - res.clearCookie('refreshToken'); res.redirect('/'); }); -// 토큰 재발급 엔드포인트 -app.post('/token', async (req, res) => { - const refreshToken = req.cookies.refreshToken; - - if (!refreshToken) return res.sendStatus(401); - - try { - const decoded = jwt.verify(refreshToken, refreshTokenSecretKey); - const user = await User.findById(decoded.userId); - - if (!user || user.refreshToken !== refreshToken) { - return res.sendStatus(403); - } - - const newAccessToken = jwt.sign( - { userId: user._id, email: user.email, name: user.name }, - secretKey, - { expiresIn: '15m' } - ); - - res.cookie('accessToken', newAccessToken, { - httpOnly: true, - secure: true, - sameSite: 'Strict', - maxAge: 15 * 60 * 1000 // 15분 - }); - - res.status(200).json({ message: '토큰 재발급 성공' }); - } catch (error) { - console.error('토큰 재발급 오류:', error); - res.sendStatus(403); - } -}); - // 대시보드 app.get('/dashboard', authenticateToken, (req, res) => { @@ -260,13 +165,20 @@ app.get('/dashboard', authenticateToken, (req, res) => { `); }); +// // 홈 +// app.get('/', (req, res) => { +// res.send(` +// <h1>Google OAuth Login</h1> +// <a href="/googlelogin">Login with Google</a> +// `); +// }); //signup 경로 app.get('/signup', (req, res) => { res.sendFile(__dirname + '/public/signup.html'); // login.html 파일 경로 설정 }); -//session 로그인 +//session // app.get('/conf_password', (req, res) => { // if (req.isAuthenticated && req.isAuthenticated()) { // 로그인 여부 확인 @@ -319,33 +231,15 @@ app.post('/login', async (req, res) => { // console.log('로그인 성공: ', user); //jwt--------------------------------------- - const accessToken = jwt.sign( + const token = jwt.sign( { userId: user._id, email: user.email, name: user.name }, secretKey, - { expiresIn: '15m' } - ); - - const refreshToken = jwt.sign( - { userId: user._id }, - refreshTokenSecretKey, - { expiresIn: '7d' } + { expiresIn: '1h' } ); - // 사용자 데이터베이스에 리프레시 토큰 저장 - user.refreshToken = refreshToken; - await user.save(); - - //https 환경에서만 - res.cookie('accessToken', accessToken, { - httpOnly: true, - secure: true, // 프로덕션 환경에서만 secure 플래그 활성화 - sameSite: 'Strict', // CSRF 방지를 위해 sameSite 옵션 설정 - maxAge: 3600000 // 1시간 (토큰 만료 시간과 동일하게 설정) - }); - res.status(200).json({ message: '로그인 성공', - accessToken: accessToken, + token: token, user: { _id: user._id, email: user.email, @@ -393,41 +287,9 @@ app.post('/signup', async (req, res) => { } }); -app.get('/auth/status', authenticateToken, (req, res) => { - res.status(200).json({ - isAuthenticated: true, - user: { - _id: req.user.userId, - email: req.user.email, - name: req.user.name - } - }); - }); - - //공동 작업 가능 소켓 -const server = https.createServer(sslOptions, app); +const server = http.createServer(app); const wss = new WebSocketServer(server); -const ws = new WebSocket('wss://localhost:8000'); - - -// app.listen(process.env.PORT, () => { -// console.log(`Server is running on http://localhost:${process.env.PORT}`); -// }); -// HTTPS 강제 적용 미들웨어 (선택 사항) -app.use((req, res, next) => { - if (req.secure || req.headers['x-forwarded-proto'] === 'https') { - next(); - } else { - res.redirect(`https://${req.headers.host}${req.url}`); - } - }); - -https.createServer(sslOptions, app).listen(process.env.PORT || 8000, () => { - console.log(`HTTPS 서버가 실행 중입니다: https://localhost:${process.env.PORT || 8000}`); - }); - -// HTTP 서버 실행 (선택 사항) -// http.createServer(app).listen(8080, () => { -// console.log('HTTP 서버가 실행 중입니다: http://localhost:8080'); -// }); \ No newline at end of file +server.listen(process.env.PORT, () => { + console.log(`Server is running on http://localhost:${process.env.PORT}`); +}); diff --git a/config/passport.js b/config/passport.js index 1ba16b7f740f6b7418c2a2cfe9282b572b934315..69eb5322d5d1e20419d8c987712036286ed09c4c 100644 --- a/config/passport.js +++ b/config/passport.js @@ -8,7 +8,7 @@ const User = require('../models/user'); passport.use(new GoogleStrategy({ clientID: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, - callbackURL: `https://localhost:${process.env.PORT}/googlelogin/redirect` + callbackURL: `http://localhost:${process.env.PORT}/googlelogin/redirect` }, async (accessToken, refreshToken, profile, done) => { const { id, displayName, emails} = profile; try { diff --git a/middleware/authMiddleware.js b/middleware/authMiddleware.js index 060661133d9bc91f2f045176928fb44e2fefa5b8..a40fc7143334a76e25b2f7f575f5b7b6b904396a 100644 --- a/middleware/authMiddleware.js +++ b/middleware/authMiddleware.js @@ -4,25 +4,17 @@ require('dotenv').config(); const secretKey = process.env.JWT_SECRET; function authenticateToken(req, res, next) { - const token = req.cookies.accessToken; // 쿠키에서 토큰 추출 - //const authHeader = req.headers['authorization']; - //const token = authHeader && authHeader.split(' ')[1]; - console.log("토큰: ", token); + const authHeader = req.headers['authorization']; + const token = authHeader && authHeader.split(' ')[1]; - if (!token) { - req.user = null; // 토큰이 없을 경우 null로 설정 - return next(); - } + if (!token) return res.sendStatus(401); - jwt.verify(token, secretKey, (err, decoded) => { - if (err) { - req.user = null; // 토큰이 유효하지 않을 경우도 null로 설정 - return next(); - } + jwt.verify(token, secretKey, (err, decoded) => { + if (err) return res.sendStatus(403); - req.user = decoded; - next(); - }); + req.user = decoded; + next(); + }); } module.exports = authenticateToken;