1. 정리
app.use(
session({
secret: "Hello!",
resave: true,
saveUninitialized: true,
})
);
- 해당 middleware는 express-session이라는 module에서 왔으며, 브라우저가 백엔드와 상호작용 할 때 마다 브라우저에 cookie를 전송
- cookie는 백엔드에서 브라우저에게 주는 정보인데 정해진 규칙이 있음
- 매번 백엔드에 request 할 때 마다 브라우저는 자동적으로 request에 cookie를 덧붙임
- 브라우저는 매번 백엔드의 localhost에 있는 URL로 request를 보낼 때 마다 cookie가 request와 함께 전송된다는 것을 알고 있음
- cookie에는 아무 정보나 넣을 수 있는데 우리는 브라우저와 백엔드의 연결을 유지하기 위해 session id를 사용
- 우리는 HTTP 프로토콜을 사용중인데, HTTP는 stateless임
- 홈페이지에 접속하면 connection이 열리고 render가 끝나면 연결이 끊김
- session id를 담는 그릇이 cookie
- cookie를 사용하여 백엔드와 프론트엔드간 정보를 교환하는 방법도 있음
- cookie는 단순히 정보를 교환하는 방법이며, 자동적으로 처리되기에 좋은 점이 있음
- 브라우저와 백엔드는 모두 session id를 가지고 있음
- 백엔드는 생성된 모든 session id를 관리하는 곳
- session store는 session을 저장하는 곳인데, 현재는 테스트를 위한 저장소를 사용하므로 서버가 재시작되면 모두 사라짐
- 이 문제를 해결하기 위해 cookie store와 mongoDB를 연결
// base.pug
if loggedIn
li
a(href="/logout") Logout
li
a(href="/my-profile") #{loggedInUser.name}
// middleware.js
export const localsMiddleware = (req, res, next) => {
res.locals.loggedIn = Boolean(req.session.loggedIn);
res.locals.siteName = "Wetube";
res.locals.loggedInUser = req.session.user;
console.log(res.locals);
next();
};
- 우리는 loggedIn을 render하지 않았는데 사용이 가능함
- locals에 loggedIn을 선언해줬기 때문
- locals는 뭐든지 할 수 있는 object이며, template이 locals object에 접근할 수 있다는 것
- pug과 express에서 이미 설정되어 있음
2. MongoStore
- https://www.npmjs.com/package/express-session
express-session
Simple session middleware for Express. Latest version: 1.18.1, last published: a month ago. Start using express-session in your project by running `npm i express-session`. There are 5038 other projects in the npm registry using express-session.
www.npmjs.com
- session id는 cookie에 저장되지만, 데이터 자체는 서버에 저장
- 서버에 저장되는 default session storage는 memory storage이고, 실제 사용하기 위해 있는게 아님
- 그래서 우리는 session store를 사용, 즉 session을 db에 저장해야 함
- https://www.npmjs.com/package/connect-mongo
connect-mongo
MongoDB session store for Express and Connect. Latest version: 5.1.0, last published: a year ago. Start using connect-mongo in your project by running `npm i connect-mongo`. There are 742 other projects in the npm registry using connect-mongo.
www.npmjs.com
app.use(
session({
secret: "Hello!",
resave: true,
saveUninitialized: true,
store: MongoStore.create({ mongoUrl: "mongodb://127.0.0.1:27017/wetube" }),
})
);
- 현재 session은 mongodb에 저장되어 있음
- db에서 show collections를 해보면 sessions폴더가 있으며 데이터가 없음
- 서버를 켜고 홈페이지에 접속하면 sessions폴더에 session이 생성된 것을 확인
- 이제는 서버를 재시작해도 session이 남아있음
{
_id: 'UYMi_6hq_-3EGeLX3ZIzCS2AtyC0Sup8',
expires: ISODate('2024-11-26T03:10:16.576Z'),
session: '{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"loggedIn":true,"user":{"_id":"6732c71293810505a8dd2eb7","email":"1@1","username":"1","password":"$2b$05$XaPAFRfH/TgoaZAABWAAzu7kl8RUiIdDzQytgLhvO.rOB7x.jQn06","name":"1","location":"usa","__v":0}}'
}
]
- session에 로그인한 계정의 정보가 담겨져 있는 것도 확인
- express 서버를 껐다 켜도 로그인도 유지되어 있음
3. resave saveUninitialized
- session authentication을 이용하면 사용하면 몇가지 문제점이 발생됨
- 우선 개발자 도구를 통해 쿠키를 강제적으로 지운 다음 새로고침하면 다시 cookie가 생성되고 session을 만들어 줌
- 만약 봇이나 구경만 하려는 사람들이 내 홈페이지에 방문했다고 가정
- 모든 방문자의 cookie와 session을 생성하여 db에 저장하면 추적은 가능하지만 좋은 방법은 아님
- 로그인한 사람의 session만 저장하는게 좋음
- resave와 saveUninitialized를 false로 변경하고 다시 홈페이지를 방문하면 cookie가 생성되지 않음
- session이 새로 만들어지고 수정된 적이 없을 때 uninitialized라는 것
- session은 controller에서 수정이 가능
// userController.js
export const postLogin = async (req, res) => {
const { username, password } = req.body;
const pageTitle = "Login";
const user = await User.findOne({ username });
if (!user) {
return res.status(400).render("login", {
pageTitle,
errorMessage: "An account with this username does not exists.",
});
}
const ok = await bcrypt.compare(password, user.password);
if (!ok) {
return res.status(400).render("login", {
pageTitle,
errorMessage: "Wrong Password",
});
}
// 여기서 session이 초기화된다는 것
req.session.loggedIn = true;
req.session.user = user;
return res.redirect("/");
};
- 즉 saveUninitialized은 session이 수정될 때만 session을 db에 저장하고 cookie를 넘겨줌
- 다른 말로 표현하면, 백엔드가 로그인한 유저에게만 cookie를 주도록 설정되어 있음
- 백엔드가 db에 session을 저장하는게 session authentication에서의 문제점 중 하나
- 이 문제를 해결하기 위한 것이 token authentication
- ios나 안드로이드 앱을 만들 때 애네들은 cookie를 갖지 않기 때문에 token을 사용
- 브라우저에서도 token을 사용할 수 있지만 현재로선 제외
- 아무튼 아직 db에 session이 없는데 로그인을 하고 다시보면 session이 생성되어 있는걸 확인
- session에는 더많은 설정이 있는데 secret은 보이면 안됨
- 웹사이트를 배포할때 db url이 그대로 노출되면 안됨
'개발 > Node.js' 카테고리의 다른 글
Dotenv / Github Login / UrlSearchParams (0) | 2024.11.12 |
---|---|
Secret Domain Expiration Etc (0) | 2024.11.12 |
Cookie Session / Express-Session / Locals (0) | 2024.11.08 |
Login / Bcrypt Compare (0) | 2024.11.08 |
Status Code (0) | 2024.11.08 |