인프런 커뮤니티 질문&답변
passport 모듈 배포 후 쿠키 저장 문제
작성
·
352
·
수정됨
0
안녕하세요!! 현재 프론트는 vue.js 백은 node.js로 개발중에 있는데요
공식 문서랑 제로초님 책 보고 따라하면서 하고 있는데
passport를 사용해서 로그인 로직을 구현했습니다
로컬에서는 쿠키 저장도 잘 되고 로그인도 잘 되는데
배포만 하면 쿠키가 생기기는 하는데 저장이 안 돼서 deserialize 가 안되어 로그인 자체가 안 되고 있습니다ㅜ
세션이 문제인가 싶어서 이번에 cookie-session으로 바꿔봤는데도 로컬에서는 되고 배포후에는 안 되고 있습니다.
배포 사이트는 둘 다 cloudtype으로 했고 도메인도 사서 설정을 해봤는데 안 됩니다ㅜㅜ
app.js 파일입니다
const express = require("express");
const cookieParser = require("cookie-parser");
const path = require("path");
const mysql = require("mysql2");
const dotenv = require("dotenv");
const morgan = require("morgan");
const session = require("express-session");
const MySQLStore = require("express-mysql-session")(session);
const passport = require("passport");
const bodyParser = require("body-parser");
const cookieSession = require('cookie-session')
const cors = require("cors");
dotenv.config({ path: path.join(__dirname, "/.env") });
const { sequelize } = require("./models");
const app = express();
const passportConfig = require("./passport");
passportConfig(); // 패스포트 설정
// 인증 라우터
const pageRouter = require("./routes/pages");
const authRouter = require("./routes/auth");
const mypageRouter = require("./routes/mypage");
const groupRouter = require("./routes/group");
const guestRouter = require("./routes/guest");
const randomRouter = require("./routes/random");
sequelize
.sync({ force: false })
.then(() => {
console.log("데이터베이스 연결");
})
.catch((err) => {
console.error(err);
});
const port = 3000;
// VARIABLES
app.set("trust proxy", 1);
app.use(
cors({
// front 서버인 127.0.0.1:8080 의 요청을 허용하도록 cors 사용
origin: [process.env.FRONT_URL_1, process.env.FRONT_URL_2],
// origin: ['http://localhost:8080', 'http://localhost:8081'],
methods: ["GET", "PUT", "POST", "PATCH", "DELETE", "OPTIONS"],
optionsSuccessStatus: 200,
credentials: true,
})
);
app.use("/uploads", express.static("uploads"));
app.use(morgan("dev")); // log
app.use(express.static(path.join(__dirname, "public"))); // 요청시 기본 경로 설정
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser(process.env.COOKIE_SECRET));
const options = {
host: process.env.DB_HOST,
port: process.env.DB_PORT,
user: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
};
// Sequelize로 설정한 MySQL 연결 객체를 사용하여 MySQL 저장소 생성
const sessionStore = new MySQLStore(options, mysql.createConnection(options));
app.use(cookieSession({
maxAge : 1000 * 60 * 60 * 24 * 7,
secret: process.env.COOKIE_SECRET, // 암호화 키
domain: [process.env.FRONT_URL_1, process.env.FRONT_URL_2],
httpOnly: true,
secure: true,
sameSite: "none",
}));
// 쿠키 세션 미들웨어 등록
// regenerate & save 오류 현상 해결
app.use(function(req, res, next) {
if (req.session && !req.session.regenerate) {
req.session.regenerate = (cb) => {
cb()
}
}
if (req.session && !req.session.save) {
req.session.save = (cb) => {
cb()
}
}
next()
})
// app.use(
// session({
// resave: false, // 세션 항상 저장할지
// saveUninitialized: true, // 세션 저장 전 Uninitialized 상태로 만들어 저장
// secret: process.env.COOKIE_SECRET, // 암호화 키
// store: sessionStore, // Sequelize로 설정한 MySQL 저장소를 사용
// // cookie: {
// // domain: [process.env.FRONT_URL_1, process.env.FRONT_URL_2],
// // httpOnly: true,
// // secure: true,
// // sameSite: "none",
// // maxAge: 1000 * 60 * 60 * 24 * 7,
// // },
// })
// );
app.use(passport.initialize()); //요청 (req 객체) 에 passport 설정
app.use(passport.session()); // req.session 객체에 passport 인증 완료 정보를 저장
// 경로 지정
app.use("/", pageRouter);
app.use("/auth", authRouter);
app.use("/mypage", mypageRouter);
app.use("/group", groupRouter);
app.use("/guest", guestRouter);
app.use("/random", randomRouter);
// 일부러 에러 발생시키기 TEST용
app.use((req, res, next) => {
const error = new Error(`${req.method} ${req.url} 라우터가 없습니다.`);
error.status = 404;
next(error);
});
app.use((err, req, res, next) => {
// 404 오류인 경우
if (err.status === 404) {
res.status(404).send("페이지를 찾을 수 없습니다.");
} else {
// 다른 오류일 경우 일반적인 오류 페이지 표시
res.status(500).send("서버 오류가 발생했습니다.");
}
});
// 에러 처리 미들웨어
app.use((err, req, res, next) => {
// 템플릿 변수 설정
res.locals.message = err.message;
res.locals.error = process.env.NODE_ENV !== "production" ? err : {}; // 배포용이 아니라면 err설정 아니면 빈 객체
res.status(err.status || 500);
res.send({
error: {
message: err.message,
},
});
});
app.listen(port, () => {
console.log(`http://localhost:${port}`);
});auth.js 파일입니다(로그인 , 로그아웃)
// 로그인
exports.login = async (req, res, next) => {
//? local로 실행이 되면 localstrategy.js를 찾아 실행
console.log("로그인 실행");
passport.authenticate("local", (authError, user, info) => {
console.log("로그인 패스포트");
console.log(authError, user, info);
// done(err)가 처리된 경우
if (authError) {
console.error(authError);
return next(authError); // 에러처리 미들웨어로 보낸다.
}
if (!user) {
return res.status(400).json({ message: "가입되지 않은 회원입니다." });
}
console.log('유저',user);
return req.login(user, (loginError) => {
if (loginError) {
console.error(loginError);
return next(loginError);
}
// req.session.save(() => {
const userData = JSON.parse(JSON.stringify(user));
delete userData.password;
console.log('유저데이터', userData);
res.json({ message: '로그인 성공', user: userData });
// });
});
})(req, res, next); // 미들웨어 내의 미들웨어에는 (req, res, next)를 붙입니다.
};
//로그아웃
// exports.logout = (req, res) => {
// req.logout(() => {
// req.session.destroy(); // passport 업데이트 이후 함수 안에 넣어야 실행됨
// res.clearCookie("connect.sid"); // connect.sid 쿠키 삭제
// res.send("로그아웃");
// });
// };
exports.logout = (req, res) => {
req.session = null; // 세션 삭제
res.clearCookie("connect.sid"); // connect.sid 쿠키 삭제
res.send("로그아웃");
};가비아에서 도메인을 사서 cloudflare로 연결했습니다
프론트에는 'https://api.smile-mbti.shop/ '로 백엔드url를 연결했고
백에는 'https://www.smile-mbti.shop', 'https://front.smile-mbti.shop'을 fronturl로 연결했습니다(쿠키, CORS 도메인)
https://github.com/w00ye0l/SMilE
깃허브 링크도 첨부합니다ㅜ
답변 1
0
안녕하세요 노은빈님, 인프런 AI 인턴이에요.
쿠키 관련 문제로 로그인이 잘 되지 않는 상황이라고 이해하고 있습니다. 문제 해결을 위해 다음과 같은 점들에 주의해 보실 수 있을 것 같습니다:
동일한 도메인이라면 쿠키의 SameSite 속성을 “None”으로 설정해야 합니다. 이를 위해 사용하는
cookie-parser와express-session패키지에서sameSite옵션을 “None”으로 설정해주셔야 합니다.배포된 사이트의 프론트엔드와 백엔드 서버 간의 도메인이 다르다면, CORS와 관련된 설정도 제대로 확인하셔야 합니다. 프론트엔드 서버에서 백엔드 서버로의 요청 시 쿠키를 전송할 수 있도록
crossOriginResourcePolicy속성 등을 설정해주셔야 합니다.배포된 사이트의 프론트엔드와 백엔드 서버 간의 시간 동기화 문제가 발생할 수 있으므로, 두 서버의 시간을 동기화하거나 시간 관련 문제를 최소화할 수 있도록 작업하셔야 합니다.
위의 사항들을 확인하고 필요한 조치를 취해보시기 바랍니다. 문제가 계속되면 더 자세한 로그나 에러 메시지를 확인하여 원인을 파악하는 것이 도움이 될 수 있습니다. 감사합니다!




