[Toy Project - Omuk] 12. 로그인-로그아웃 확인 미들웨어 및 템플릿 엔진 응용
권한 미들웨어
로그인을 하려고 할 때, 이미 로그인 된 상태라면 다시 로그인 할 필요가 없습니다. 마찬가지로 회원가입도 필요가 없습니다. 그렇기 때문에 로그아웃이 된 상태에서만 요청이 가능하도록 구현해야 합니다. 반대로, 로그인한 상태여야 로그아웃을 할 수 있도록 해야 합니다.
그래서 이러한 조건을 충족시키기 위해서 권한이 있는지 없는지 체크할 필요가 있습니다. 그래서 해당 라우트로 특정 요청이 들어올 때 미들웨어를 거치도록 합니다.
루드 디렉터리에서 middlewares 폴더를 생성하고 그 폴더에서 authCheck.js 파일을 만듭니다. 그리고 두 가지 미들웨어를 export 해줍니다.
export function isLoggedIn(req, res, next) {
if (req.isAuthenticated()) {
next();
} else {
res.status(403).send("로그인이 필요합니다");
}
}
export function isNotLoggedIn(req, res, next) {
if (!req.isAuthenticated()) {
next();
} else {
const message = encodeURIComponent("로그인 한 상태입니다");
res.redirect(`/?error=${message}`);
}
}
이제 로그인, 회원가입 라우터와 로그아웃 라우터에 해당 미들웨어를 넣어줍니다.
로그아웃 컨트롤러는 아래와 같이 구현하였습니다. 기존의 방법에서 조금 변경된 내용이 있습니다.
/** 로그아웃 */
const logOut = (req, res) => {
req.logout((err) => {
req.session.destroy();
if (err) return next(err);
else res.redirect("/");
});
};
서버 사이드 렌더링
passport를 통해서 구현한 로그인, 로그아웃을 통해서 세션을 redis에 저장하여 클라이언트가 인증에 성공할시 세션값을 부여하도록 사용했습니다.
이제 사용자의 세션에 저장된 값을 이용하여 요청 객체에 저장하고 라우터에서 그 객체를 사용할 수 있게 되는 것입니다. 이를 적절히 활용해서 템플릿 엔진에서도 사용해보도록 하겠습니다.
일단, passport의 deserializeUser를 통해서 req.user에 저장되는 정보를 res.locals.user에 저장해주도록 합시다. 일단 로그인된 후에 루트 디렉터리로 리다이렉트될 때 res.locals.user에 정보가 저장되어 뷰 엔진에서 user 객체를 사용할 수 있게 됩니다.
일단 user 객체를 사용하기 위해 미들웨어를 설정합니다.
router.use((req, res, next) => {
res.locals.user = req.user;
next();
});
이제 뷰엔진에서 해당 정보를 사용하려고 합니다. 저는 로그인했을 때, 로그인/회원가입 버튼이 보이지 않도록 설정했습니다.
<div id="sign">
{{#if user}}
<div class="sign auth">
<div class="user">{{user.dataValues.nickname}}님 안녕하세요.</div>
<a href="/auth/logout">로그아웃</a>
</div>
{{else}}
<div class="sign body">
<a href="/auth/signin">로그인/회원가입</a>
</div>
{{/if}}
</div>
user 객체가 있으면 로그인이 된 것이기 때문에 핸들바의 if 조건문을 사용했습니다. 로그인한 상태일 때는 로그아웃 버튼과 유저에 대한 인사를, 로그아웃-로그인하지 않은 상태일 때는 로그인/회원가입 버튼을 구현했습니다.
서버를 시작하여 테스트해보겠습니다. 카카오로 로그인했을 때의 화면입니다.
로그아웃 버튼을 누르면 아래와 같이 다시 로그인/회원가입 버튼으로 바뀝니다.
로컬 로그인에서도 동일하게 작동합니다.