2023. 8. 22. 19:24ㆍ공부 중/Node.js
0. 출처
오픈튜토리얼 생활코딩 참고.
1. UI 반영
// ./lib/auth.js
module.exports.statusUI = (req, res, next)=>{
let authStatusUI = `<a href="/auth/login">login</a>`;
if(req.session.is_logined){
authStatusUI = `${req.session.nickname} - <a href="/auth/logout">logout</a>`
}
req.authStatusUI = authStatusUI;
next();
}
로그인 상태에 따라서 다른 authStatusUI를 생성함.
// ./lib/template.js
module.exports.HTML= (req,res,next)=>{
const html = `
...
<body>
<div id="top">
<h1><a href="/">Board</a></h1>
<input id="nightDayBtn" type="button" value="night" onclick="changeDarkMode()"/>
${req.authStatusUI} //변경
</div>
html에 req.authStatusUI를 추가한다.
// ./routes/index.js, ./routes/topic.js, ./routes/auth.js
const auth = require('../lib/auth')
//모든 get method에 auth.statusUI를 추가.
router.get('/', (req,res,next)=>{
...
next();
},[auth.statusUI,template.List,template.HTML]);
모든 get method에 auth.statusUI 미들웨어를 추가한다.
login 상태 | logout 상태 |
세션 데이터를 읽어서 로그인한 상태인지 확인한다.
로그인한 경우 닉네임과 logout 링크를 보여준다.
로그인하지 않은 경우는 login 링크를 보여준다.
2. 로그아웃
logout 링크를 클릭하면 실제로 로그아웃하도록 만들자.
// ./routes/auth.js
...
router.get('/logout', (req, res, next)=>{
req.session.destroy((err)=>{
if(err) console.log(err);
res.redirect('/');
});
})
Session.destory()
를 사용해서 세션을 삭제한다.
그런 다음 /
로 리다이렉션 한다.
세션이 삭제되었다.
3. 접근 제어
- 로그인했을 때만
/
에서는 create가,/topic/...
에서는 create, update, delete 버튼이 보이도록 하자. - post로 create, update, delete 요청이 들어오면 로그인했는지 확인하고 요청을 처리한다.
- 만약 로그인 되어있지 않다면
/auth/login
으로 리다이렉션 시키자.
가. 로그인 했을때만 버튼이 보이도록 수정
// ./routes/index.js
router.get('/', (req,res,next)=>{
req.title = "Welcome :)";
req.desc = "Here is for to test node.js server :)";
req.control = `
<input type="button" value="create" onclick="redirect(this,'')"/>
`;
req.author = '';
next();
},[auth.statusUI,template.List,template.HTML]);
// ./routes/topic.js
router.get('/:pageId', (req, res, next)=>{
...
req.control = `
<input type="button" value="create" onclick="redirect(this, '')"/>
<input type="button" value="update" onclick="redirect(this, '${pageId}')"/>
<form id="frm" action="/topic/delete" method="post" style="display:inline">
<input type="hidden" name="id" value="${pageId}">
<input type="button" value="delete"
onclick="if(confirm('really delete?')==true){document.getElementById('frm').submit();}">
</form>
`;
req.author = `${topic[0].name} 작성`;
next();
},template.HTML);
create, update, delete 버튼은 req.control에 위치한다.
req.control = '';
if(req.session.is_logined) req.control = `...`;
위와 같이 수정한다.
login 상태에서는 버튼이 보임. | logout 상태에서는 버튼이 보이지 않음. |
나. POST 요청이 들어오면 로그인 했는지 확인
// ./lib/auth.js
...
module.exports.checkLogin = (req, res, next)=>{
if(req.session.is_logined) next();
else res.redirect('/auth/login');
}
로그인 상태면 계속 진행하고, 그렇지 않으면 로그인 화면으로 리다이렉션 한다.
// ./routes/topic.js
router.route('/create')
.post(auth.checkLogin, (req,res,next)=>{
...
router.post('/update',auth.checkLogin, (req,res,next)=>{
...
router.post('/delete', auth.checkLogin, (req,res,next)=>{
post 요청을 처리하기 전에 auth.checkLogin을 실행한다.
정상적으로 동작했지만 login 링크는 버그가 발생함.
버그가 발생한 이유는 ./routes/auth.js
에 auth.statusUI
를 추가하지 않았기 때문이다.
router.route('/login')
.get(auth.statusUI,template.List,(req,res,next)=>{
4. 세션 저장
req.session.save(function(err){…})
: 세션을 store에 저장. 해당 메서드는 session 데이터의 변경이 발생하면 HTTP response의 마지막에 자동적으로 호출된다. 그래서 일반적으로 사용할 일이 없다. 하지만 리다이렉션, long-lived requests, webSocket을 사용할 경우 호출해야 할 수 있다.즉, 응답을 보내기 전에 세션 변경사항이 저장소에 반영되도록 할 수 있습니다.
일전에 session.save()
관하여 공부했었다.
지금 코드에는 redirect()
와 session.save()
가 동시에 실행된다.
운이 나쁘면 수정된 세션 데이터가 반영되기 전에 리다이렉션이 실행될 수 있다.
이런 문제를 해결하기 위해서 session.save()
를 추가한다.
// ./routes/auth.js
router.route('/login')
.get(auth.statusUI, template.List,(req,res,next)=>{
...
},template.HTML)
.post((req,res,next)=>{
...
if(email == authData.email && password == authData.password){
req.session.is_logined = true;
req.session.nickname = authData.nickname;
req.session.save((err)=>{
if(err) console.log(err);
//res.redirect('/');
res.send(`<script>window.alert("삑! ${authData.nickname}님 환영합니다.");window.location.href = '/';</script>`);
});
}else{
res.send(`<script>window.alert("삐빅! 틀렸습니다. 다시 시도하세요");window.location.href = '/auth/login';</script>`);
}
});
req.session.save((err)=>{...});
: 저장 후 콜백 함수 실행.
'공부 중 > Node.js' 카테고리의 다른 글
[Express] Passport.js 시작하기 (0) | 2023.09.17 |
---|---|
[Express] Passport.js이란? (0) | 2023.09.17 |
[Express] Session으로 인증 구현하기_1 (0) | 2023.08.22 |
[Express] Session이란? (0) | 2023.08.19 |
[Node.js] 쿠키의 한계 (0) | 2023.08.10 |