next
매개변수의 2가지 사용방법
Middleware
는 req
, res
, next
...등 3개의 매개변수를 사용한다.
router.post('/', (req, res, next) => {
res.json({ id: 1, content: 'Hello1' });
});
이 중 next
는 인자 유무를 통해 다음과 같이 개별적인 사용방법을 제공한다.
인자에 Error
를 포함한다면 next
는 에러를 처리하는 Middleware
로 이동한다.
에러처리 Middleware
는 app.js
의 다음과 같이 내부적으로 존재하며, 필요에 따라 커스텀하여 사용할 수 있다.
if (err) {
console.error(err);
return next(err);
}
// app.js
app.use('/user', userRouter);
// 코드상에는 없지만 에러처리 Middleware가 존재
app.listen(3065, () => {
console.log('서버 실행 중');
});
// app.js
app.use('/user', userRouter);
// 에러처리 Middleware Custom
app.use((err, req, res, next) => {
});
app.listen(3065, () => {
console.log('서버 실행 중');
});
인자를 포함하지 않는다면 next
는 다음 Middleware
로 이동한다.
exports.isLoggedIn = (req, res, next) => {
if (req.isAuthenticated()) {
next(); // 다음 Middleware로 이동
}
};
Custom Middleware
는Router
에 존재하는 코드의 중복을 제거
앞선 포스팅에서 소개한 로그인, 로그아웃 Router
의 요청 주소는 공개되어있기 때문에 보안상 위험을 방지하기 위해 Middleware
로 검사한다.
이 때 Router
별로 보안 검사를 수행하면 코드의 중복이 발생하기 때문에 이러한 문제를 해결하기 위해 Custom Middleware
를 사용한다.
Custom Middleware
를 사용하는 방법은 다음과 같다.
middlewares.js
라는 개별 파일을 생성하여 아래와 같이 Router
를 검사하는 Custom Middleware
를 작성한다.
// routes/middlewares.js
exports.isLoggedIn = (req, res, next) => {
if (req.isAuthenticated()) { // req.isAuthenticated() === true -> 로그인한 사용자
next(); // 다음 Middleware로 이동
} else {
res.status(401).send('로그인이 필요합니다.'); // 클라이언트 오류
}
};
exports.isNotLoggedIn = (req, res, next) => {
if (!req.isAuthenticated()) { // req.isAuthenticated() === false -> 로그인하지 않은 사용자
next(); // 다음 Middleware로 이동
} else {
res.status(401).send('로그인하지 않은 사용자만 접근 가능합니다.'); // 클라이언트 오류
}
};
사용하고자 하는 Router
에서 Custom Middleware
를 실행한다.
// routes/user.js
const express = require('express');
const bcrypt = require('bcrypt');
const passport = require('passport');
const { User, Post } = require('../models');
const { isLoggedIn, isNotLoggedIn } = require('./middlewares'); // middelware 불러오기
const router = express.Router();
// login router가 실행되면 isNotLoggedIn Middleware가 실행된다.
// 만약 로그인하지 않은 사용자일 경우 next()가 실행되어 다음 middleware((req, res, next) => {...})가 실행
router.post('/login', isNotLoggedIn, (req, res, next) => {
passport.authenticate('local', (err, user, info) => {
if (err) {
console.error(err);
return next(err); // 에러처리 middleware로 이동
}
:
:
})(req, res, next);
});
// logout router가 실행되면 isLoggedIn Middleware가 실행된다.
// 만약 로그인한 사용자일 경우 next()가 실행되어 다음 middleware((req, res) => {...})가 실행
router.post('/logout', isLoggedIn, (req, res) => {
req.logout(() => {
res.redirect('/');
});
req.session.destroy();
res.send('ok');
});
module.exports = router;
Node.js 공식문서
Node.js 교과서 - 조현영
React로 NodeBird SNS 만들기 - 제로초