본문 바로가기

[B] Node Note

Express 미들웨어(1)

** 본 게시물은 "Node.js 교과서(길벗)" 를 학습하면서 요약 한것임


//---------------------------------------------------------------------------------
// 6.3.1 커스텀 미들웨어 만들기(p194)
//---------------------------------------------------------------------------------
// [요청 --> next()]
// [미들웨어 --> next()]
//     - < 커스터 미들웨어 위치 >
//      - logger
//     - logger(morgan)
//      - json, urlencoded
//      - cookieParser
//      - static
//      - indexRouter
//      - usersRouter
//     - 404 처리 미들웨어
//      - error handler
//  [응답]
//---------------------------------------------------------------------------------
// 6.3.2 morgan
//---------------------------------------------------------------------------------
// 현재 콘솔에 나오는 로그는 모두 morgan 미들웨어에서 나오는 것
GET / 304 3.617 ms - -
/stylesheets/style.css 커스텀 미들웨어~~
GET /stylesheets/style.css 304 1.360 ms - -
//
// web.js에서 아래와 같이 사용됨
// * 보통 개발시에는 short 나 dev
// 배포시에는 common 이나 combined 를 사용함
// * 콘솔뿐 아니라 파일이나 데이터베이스에 로그를 남길수 있는 모듈 ==> winston ( >> 15.1.6)    
//
var logger = require('morgan'); 

    :

app.use(logger('dev'));

//---------------------------------------------------------------------------------
// 6.3.3 body-parser (p199)
//--------------------------------------------------------------------------------- 
//
var bodyParser = require('body-parser');
    :
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
    :
// 익스프레스 4.16.0 버전 부터는 익스프레스에 내장되었기 때문에 web.js에 별도로 기술하지 않음

// JSON은 JSON 형식의 데이터 전달 방식,
// URL-encoded는 주소 형식으로 데이터를 보내는 방식(form 전송)
// { extented: false} : 노드의 querystring 모듈을 사용하고
// { extented: ture } : qs 모듈을 사용하여 쿼리 스트링을 해성함
// ** qs 모듈은 외장모듈로 querystring 기능을 조금 확장한 모듈임

// 4.3절 POST, PUT 요청의 본문을 전달 받으려면 req.on('data')와 req.on('end)로 스트림을 사용했으나
// body-parser를 사용하면 그럴 필요가 없음( 내부적으로 본문을 해석해 req.body에 추가 해줌)  

// body-parse가 모든 본문을 해석해주는 것은 아님( >> 9.4절 Multer 참고 )  
    
// 단, Raw, Text 형식의 본문인 경우에는 body-parser를 설치한 후 다음과 같이 추가함
app.use(bodyParser.raw());
app.use(bodyParser.text());

// 과제 : excel import/export 기능 구현

//---------------------------------------------------------------------------------
// 6.3.4 cookie-parser (p200)
//--------------------------------------------------------------------------------- 
//
var cookieParser = require('cookie-parser');
    :
app.use(cookieParser());
    :
// 해석된 쿠키들은 req.cookies 객체에 들어감
// 예를 들어, name=zerocho 쿠키를 보냈다면 req.cookies는 { name: 'zorochoi' }가 됨
    

//---------------------------------------------------------------------------------
// 6.3.5 static (p201)
//--------------------------------------------------------------------------------- 
// static 미들웨어는 정적인 파일들을 제공함(내장 모듈)
// cf) const static = require('serve-static');
//  
app.use(express.static(path.join(__dirname, 'public')));

// 함수의 인자로 정적 파일들이 담겨 있는 폴더를 지정하여 외부에서 접근할 수 있게 됨
// 실제 서버 폴더 경로에는 public이 들어 있지만 요청 주소에는 들어 있지 않다!!
// 이는 외부에서 서버의 구조를 쉽게 파악하지 못하도록 하는 것임

//---------------------------------------------------------------------------------
// 6.3.6 express-session (p202)
//---------------------------------------------------------------------------------
// 세션관리용 미들웨어, 로그인 등의 이유로 세션을 구현할 때 매우 유용함
// express-generration로 설치되지 않으므로 직접 설치함(설치 위치는 cafe24 밑에서)
// > npm i express-session

var session = require('express-session');
    :
app.use(cookieParser('secret code'));
app.use(session({
    resave: false,
    saveUninitialized: false,
    secret:'secret code',
    cookie: {
        httpOnly: true,
        secure: false
    }
}));

// express-session은 인자로 센션에 대한 설정을 받음
// - resave : 요청이 왔을때 세션에 수정 사항이 생기지 않더라도 세션을 다시 저장할지 여부 설정
// - saveUninitialized : 세션에 저장할 내역이 없더라도 세션을 저장할지 여부 설정
// - secret(필수) : cookie-parser의 비밀키와 같은 역할을 함
//      express-session은 세션 관리시 클라이언트에 쿠키를 보냄( 이를 "세션 쿠키" 라고 함)
//      안전하게 쿠키를 전송하려면 쿠키에 서명을 추가해야 하고
//      쿠키를 서명하는데 seret의 값이 필요함
//      cookie-parser의 secret과 같게 설정함
// - cookie : 세션 쿠키 설정
// maxAge, domain, pathh, expires, sameSite, httpOnly, secure 등 일반적인 쿠키 옵션이 모두 제공됨
//      httpOnly 를 사용해서 클라이언트에서 쿠키를 확인하지 못하도록 함
//      secure: false > http가 아닌 환경에서도 사용할 수 있음
//      ** 배포시에는 https를 적용하고 secure도 true로 설정하는 것이 좋음
//       store 옵션 : 현재는 메모리에 서션을 저장하지만 데이터베이스를 연결하여 세션을 유지하는 것이 좋다
//       # 보통 레디스(Redis)가 자주 쓰임( >>> 15.1.8 ) 
//

//---------------------------------------------------------------------------------
// 6.3.7 connect-flash (p204)
//---------------------------------------------------------------------------------
// 일회성 메시지를 웹브라우저에 나타낼 때 사용
// cookie-parse, express-session을 사용하므로 이들 보다 뒤에 위치함
// > npm i connect-flash
var flash = require('connect-flash');       
    :
app.use(flash());

// flash 미들웨어는 req 객체에 req.flash 메서드를 추가함(?)
// req.(키, 값) 으로 해당 키에 값을 설정하고,
// req.flash(키) 로 해당 키에 대한 값을 불러옵니다.

// [실습] users.js
var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});

//----------------------------------------------------------
// 6.3.7 connect-flash
//----------------------------------------------------------
router.get('/flash', function(req, res){
req.session.message = '세션 메시지';
req.flash('message','flash 메시지');
res.redirect('/users/flash/result');
});

router.get('/flash/result', function(req, res){
res.send(`${req.session.message} : ${req.flash('message')}`);
});

//------------------------------------------------------------
// http://localhost:8001/users/flash/ 로 접속하고, 다시 접속하면
// req.flash('message') 는 조회 되지 않음!! (p205~p206)
//------------------------------------------------------------

module.exports = router;

// 너무 많은 미들웨어를 연결하면 응답속도가 느려질 수 있으므로
// 꼭 필요한 미들웨어만 사용하자!!