공식문서에 따른 express-session의 기본 설정 방법입니다
import express from "express";
import session from "express-session";
import * as expressSession from "express-session";
import mysqlSession from "express-mysql-session";
const app = express();
const MySQLStore = mysqlSession(expressSession);
const sessionStore = new MySQLStore({}, pool as any); //저장소를 mysql로 한다.
//session 미들웨어를 사용하여 req.session 객체를 사용할수있게 된다.
app.use(
session({
secret: "secret key!",
resave: false,
saveUninitialized: false,
store: sessionStore,
cookie: { maxAge: 60 * 1000 * 30 },
})
);
express-session 미들웨어에서 resave와 saveUninitialized 옵션을 설정하는 것은 보안 및 성능 측면에서 중요한 결정입니다. 일반적으로는 false로 설정하는것을 권장하고 있습니다.
간단하게 설명하자면,
- resave: false 옵션은 세션 데이터가 변경되지 않은 경우에도 세션을 다시 저장하지 않도록 하는 것입니다. 이렇게 하면 성능이 향상됩니다. 세션 데이터가 변경되지 않는 한 매 요청마다 세션을 다시 저장할 필요가 없기 때문입니다. resave를 true로 설정하면 매 요청마다 세션을 저장하게 되므로 서버의 부하가 증가할 수 있습니다.
- saveUninitialized: false 옵션은 초기화되지 않은 세션도 저장하지 않도록 하는 것입니다. 이렇게 하면 사용자가 세션 데이터를 변경하지 않은 경우에도 빈 세션을 저장하지 않아 보안 측면에서 유리합니다. 사용자가 로그인하지 않았을 때도 세션을 생성하지 않기 때문에 불필요한 세션 데이터가 생성되지 않습니다.
- 추가로 maxAge 옵션은 세션의 유효기간을 설정하는 데 사용됩니다. maxAge는 세션 데이터가 클라이언트 브라우저에 저장되는 쿠키의 지속 시간을 제어하며, 이 값은 밀리초 단위로 설정됩니다.
일부 세션 데이터를 초기화하고 저장해야 하는 특별한 상황이 있다면 saveUninitialized를 true로 설정할 수도 있습니다. 하지만 이 경우에도 resave는 보통 false로 유지하는 것이 좋습니다.
아이디,비밀번호 입력후 로그인 버튼을 눌렀을때 작동되는 컴포넌트입니다.
import axios from "axios"
const onClickJoin = () => {
axios.post(`url/login`, {
userId: id,
userPw: password,
},{ withCredentials: true })
.then((res) => {
const status = res.status;
if (status === 200) {
router.push("/");
}
})
.catch((err) => console.log(err));
};
withCredentials 옵션은 단어 그대로, 다른 도메인에 요청을 보낼 때 요청에 인증정보를 담아서 보낼 지를 결정하는 항목입니다.
즉, 쿠키나 인증 헤더 정보를 포함시켜 요청하고 싶다면, 클라이언트에서 API 요청 메소드를 보낼때 withCredentials 옵션을 true로 설정해야합니다.
app.post("/login", async (req, res) => {
try {
const userId = req.body.userId;
const userPw = req.body.userPw;
const isUser = (await conn.query(
"SELECT * FROM user WHERE login_id = ? AND login_password = ?",
[userId, userPw]
)) as any;
const result = isUser[0];
if (Array.isArray(result) && result.length > 0) {
if (req.session) {
req.session.uid = result[0].id;
req.session.user_id = result[0].login_id;
req.session.isLogined = true;
req.session.save((err) => {
if (err) {
res.status(400).json({ message: err });
}
res.status(200).json({ message: req.sessionID });
});
} else {
console.log("no session");
}
} else {
console.log("result no id");
}
} catch (err) {
res.status(500).json({ error: "post login error", message: err });
}
});
post요청하며 받은 userId와 userPw를 통해 mysql user table에 존재하는지 검사합니다.
검사를 통과했다면,
req.session을 통해 원하는 값을 추가합니다.
app.get("/", (req, res) => {
try {
if (req.session.isLogined) {
return res.send({
isLogin: true,
user_Uid: req.session.uid,
user_Id: req.session.user_id,
});
} else {
return res.send("nologin");
}
} catch (err) {
res.status(500).json({ error: "mainpage error", message: err });
}
});
세션을 확인하려면 request객체를 통해 세션 데이터에 액세스하면 됩니다.
해당 session의 isLogined 이 true일시 해당유저의 데이터를 전송해줍니다.
응답을 확인해보면
로그아웃
app.get("/logout", async (req, res) => {
try {
req.session.destroy((err) => {
req.session;
if (err) {
res.status(400).json({ message: err });
}
res.status(200).json({ message: req.sessionID });
});
} catch (err) {
res.status(500).json({ error: "get logout error", message: err });
}
});
req.session.destroy() 메서드를 사용하여 현재 세션을 제거합니다.
이로써 서버에서 세션 데이터가 삭제됩니다.
'Cooka프로젝트 > 로그인기능' 카테고리의 다른 글
crypto모듈을 사용해 암호화 (0) | 2023.09.22 |
---|---|
session 이란 ? (0) | 2023.09.18 |