Node.js/Express.js

[Toy Project - Omuk] 12. 로그인-로그아웃 확인 미들웨어 및 템플릿 엔진 응용

턴태 2022. 9. 12. 13:59

권한 미들웨어

로그인을 하려고 할 때, 이미 로그인 된 상태라면 다시 로그인 할 필요가 없습니다. 마찬가지로 회원가입도 필요가 없습니다. 그렇기 때문에 로그아웃이 된 상태에서만 요청이 가능하도록 구현해야 합니다. 반대로, 로그인한 상태여야 로그아웃을 할 수 있도록 해야 합니다.

 

그래서 이러한 조건을 충족시키기 위해서 권한이 있는지 없는지 체크할 필요가 있습니다. 그래서 해당 라우트로 특정 요청이 들어올 때 미들웨어를 거치도록 합니다.

 

루드 디렉터리에서 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 조건문을 사용했습니다. 로그인한 상태일 때는 로그아웃 버튼과 유저에 대한 인사를, 로그아웃-로그인하지 않은 상태일 때는 로그인/회원가입 버튼을 구현했습니다.

 

서버를 시작하여 테스트해보겠습니다. 카카오로 로그인했을 때의 화면입니다.

로그아웃 버튼을 누르면 아래와 같이 다시 로그인/회원가입 버튼으로 바뀝니다.

로컬 로그인에서도 동일하게 작동합니다.