본문 바로가기

Node.js

Node.js express 모듈



  • http 모듈로 웹 서버를 생성하면 굉장히 많은 일을 직접 처리해야 한다.
  • express 모듈은 http 모듈에 여러 기능을 추가해 쉽게 사용할 수 있게 마든 모듈이다.

[ express 설치 ]

$ npm install express



1. 기본 서버

[ 코드 - 모듈 추출 ]

//모듈을 추출한다.

var http = require('http');

var express = require('express');

  • express 모듈로 서버를 실행하려면 http 모듈이 필요하다.

[ 코드 - express 모듈을 사용한 서버 생성 및 실행 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');

//서버를 생성한다.
var app = express();

//request 이벤트 리스터를 설정한다.
app.use(function (request, response) {
    response.writeHead(200, {'Content-Type' : 'text/html'});
    response.end('<h1>Hello express</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});


[ 실행 - express 모듈을 사용한 서버 ]


2. 기본 응답 메서드

app.use(function (request, response) {

    response.writeHead(200, {'Content-Type' : 'text/html'});
    response.end('<h1>Hello express</h1>');
});
  • request 이벤트 리스너의 매개변수에는 request 객체와 response 객체가 들어간다.
  • express 모듈로 서버를 생성하면 request 객체와 response 객체에 다양한 기능이 추가된다.

[ response 객체의 메서드 ]
  • response.send() : 매개변수의 자료형에 따라 적절한 형태로 응답한다.
  • response.json() : JSON 형태로 응답한다.
  • response.jsonp() : JSONP 형태로 응답한다.
  • response.redirect() : 웹 페이지 경로를 강제로 이동한다.


[ send() 메서드의 매개변수 ]

  • 문자열 : HTML
  • 배열 : JSON
  • 객체 : JSON
  • 매개변수의 자료형에 따라 적절한 형태로 응답한다.

[ 코드 - send() 메서드 ]

//모듈을 추출한다.

var http = require('http');

var express = require('express');


//서버를 생성한다.

var app = express();


//request 이벤트 리스너를 설정한다.

app.use(function (request, response) {

    //데이터를 생성한다.

    var output = [];

    for (var i = 0; i < 3; i++) {

        output.push({

            count: i,

            name: 'name - ' + i

        })

    }


    //응답한다.

    response.send(output);

});


//서버를 실행한다.

http.createServer(app).listen(52273, function () {

    console.log('Server running at http://127.0.0.1:52273');

});


[ 실행 - send() 메서드를 사용한 JSON 전달 ]

  • send() 메서드에 자바스크립트 객체를 입력했으므로 JSON 형식으로 출력된다.
[ 코드 - 404 코드 전달 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(function (request, response, next) {
    //응답한다.
    response.send(404, '<h1>ERROR</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});


[ 실행 - send() 메서드를 사용한 오류 전달 ]


[ 실행 - 개발자 도구를 통해 확인 ]

  • 사파리 브라우저에서 제공하는 [ 개발자용 > 웹 속성 보기 ]를 통하여 상태가 404 임을 확인할 수 있다.
  • IE나 크롬에서도 개발자 도구를 통해 네트워크 상태를 확인할 수 있다.

3. 기본 요청 메서드
[ request 객체의 메소드 ]
  • header() : 요청 헤더의 속성을 지정 또는 추출한다.
  • accepts() : 요청 헤더의 Accept 속성을 확인한다.
  • param() : 요청 매개변수를 추출한다.
  • is() : 요청 헤더의 Content-Type 속성을 확인한다.

3.1 요청 헤더의 속성 추출
  • header() 메서드를 사용하면 쉽게 요청 헤더의 속성을 지정하거나 추출할 수 있다.

[ 코드 - User-Agent 속성 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(function (request, response) {
    //User-Agent 속성을 추출한다.
    var agent = request.header('User-Agent');

    console.log(request.headers);
    console.log(agent);

    //응답한다.
    response.send(200);
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});

[ 실행 - User-Agent 속성 ]

  • 웹 브라우저에 http://127.0.0.1:52273 에 들어가면 터미널에서 웹 브라우저의 헤더 정보를 볼 수 있다.

[ 코드 - User-Agent 속성에 따른 응답 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(function (request, response) {
    //User-Agent 속성을 추출한다.
    var agent = request.header('User-Agent');

    //브라우저를 구분한다.
    if (agent.toLowerCase().match(/chrome/)) {
        //페이지를 추출한다.
        response.send('<h1>Hello Chrome .. !</h1>');
    } else {
        //페이지를 출력한다.
        response.send('<h1>Hello express .. !</h1>');
    }
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});
  • 헤더의 속성을 추출하여 브라우저가 크롬인지 확인할 수 있다.
[ 실행 - 크롬으로 접속 ]


[ 실행 - 사파리로 접속 ]



3.2 요청 매개변수 추출
[ 코드 - param() 메서드를 사용한 요청 매개변수 추출 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(function (request, response) {
    //변수를 선언한다.
    var name = request.param('name');
    var region = request.param('region');

    //응답한다.
    response.send('<h1>' + name + '-' + region + '</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});

[ 실행 - param() 메서드를 사용한 요청 매개변수 추출 ]

  • http://127.0.0.1:52273/?name=rint&region=seoul 로 접속한 화면이다. name과 region 매개변수 값을 출력한다.

4 미들웨어 개요
  • http 모듈과 express 모듈의 가장 큰 차이점은 바로 request 이벤트 리스너를 연결하는데 use() 메서드를 사용한다는 점이다.
  • use() 메서드는 여러 번 사용할 수 있다.
  • use() 메서드의 매개변수에는 function (request, response, next) { } 형태의 함수를 입력한다.
  • 매개변수 next는 다음에 위치하는 함수를 의미한다.
[ 코드 - 미들웨어 ]
//모듈을 사용한다.
var http = require('http');
var express = require('express');

//서버를 생성한다.
var app = express();

//미들웨어 설정(1)
app.use(function (request, response, next) {
    console.log('첫 번째 미들웨어');
    next();
});

//미들웨어 설정(2)
app.use(function (request, response, next) {
    console.log('두 번째 미들웨어');
    next();
});

//미들웨어 설정(3)
app.use(function (request, response, next) {
    console.log('세 번째 미들웨어');

    //응답한다.
    response.writeHead(200, {'content-Type' : 'text/html'});
    response.end('<h1>express Basic</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});

[ 실행 - 웹 브라우저 출력 ]


[ 실행 - 콘솔 화면 ]

  • use() 메서드의 매개변수로 입력한 함수가 차례대로 실행된다.
  • 요청의 응답을 완료하기 전까지 요청 중간중간에서 여러 가지 일을 처리할 수 있다.
  • 그래서 use() 메서드의 매개변수에 입력하는 함수를 '미들웨어'라고 부른다.

§미들웨어를 사용하는 이유
  • 미들웨어에서 request 객체와 response 객체에 속성 또는 메서드를 추가하면 다음 미들웨어에서 추가한 속성과 메서드를 사용할 수 있다.


[ 코드 - 미들웨어를 사용한 속성 추가 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(function (request, response, next) {
    //데이터를 추가한다.
    request.number = 52;
    response.number = 273;
    next();
});
app.use(function (request, response, next) {
    //응답한다.
    response.send('<h1>' + request.number + ' : ' + response.number + '</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});

[ 실행 - 미들웨어를 사용한 속성 추가 ]

  • 미들웨어를 사용하면 특정한 일을 수행하는 모듈을 분리해서 만들 수 있다.

[ express 모듈의 미들웨어 ]
  • logger : 로그 정보를 출력한다.
  • csrf : CSEF 보안을 수행한다.
  • basicAuth : 기본적인 인증을 수행한다.
  • bodyParser : POST 요청 매개변수를 추출한다.
  • cookieParser : 쿠키를 분석한다.
  • session : 세션 처리를 수행한다.
  • methodOverride : 다양한 요청 방식을 수행할 수 있게 한다.
  • responseTime : 응답 시간을 계산한다.
  • router : 페이지 라우트를 수행한다.
  • staticCache : static 미들웨어를 위한 메모리 캐시 층을 생성한다.
  • static : 특정 폴더를 서버의 루트 폴더에 올린다.
  • directory : 서버의 디렉토리 구조를 보여준다.
  • vhost : 가상 호스트를 설정한다.
  • favicon : 파비콘을 생성한다.
  • limit : POST 요청의 데이터를 제한한다.
  • errorHandler : 예외 처리를 수행한다.
  • 미들웨어를 사용하면 다른 사람이 만든 기능을 추가할 수도 있고 자신이 과거에 만든 코드도 재사용하기 편리하다.

5. morgan 미들웨어
  • morgan 미들웨어는 웹 요청이 들어왔을 때 로그를 출력하는 미들웨어이다.
  • express 3.x 버전에서는 express.logger()를 사용했으나 express 4.x 버전부터는 지원하지 않는다. 따라서 morgan 모듈을 설치하여 사용하고자 한다.
[ morgan 모듈 설치 ]
$ npm install morgan

[ 코드 - morgan 미들웨어 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var morgan = require('morgan'); //express 4.x 버전부터는 express.logger()를 지원하지 않으니 morgan 모듈을 설치하여 사용한다.

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
//app.use(express.logger()); //express 3.x 용
app.use(morgan('combined')); //express 4.x 용
app.use(function (request, response) {
    response.send('<h1>express Basic</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});

[ 실행 - morgan 미들웨어 ]


[ morgan 미들웨어의 토큰 ]

  • :req[header]    요청 헤더를 나타낸다.
  • :res[header]    응답 헤더를 나타낸다.
  • :http-version   HTTP 버전을 나타낸다.
  • :response-time  응답 시간을 나타낸다.
  • :remote-addr    원격 주소를 나타낸다.
  • :date[format]   요청 시간을 나타낸다.
  • :method         요청 방식을 나타낸다.
  • :url            요청 URL을 나타낸다.
  • :referrer       이전 URL을 나타낸다.
  • :User-Agent     사용자 에이전트를 나타낸다.
  • :status         상태 코드를 나타낸다.

[ 코드 - morgan 미들웨어의 토큰 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var morgan = require('morgan');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(morgan(':method + :date'));
app.use(function (request, response) {
    response.send('<h1>express Basic</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});
  • 웹 브라우저로 http://127.0.0.1:52273 을 호출할 때마다 콘솔에 :method와 :date 에 대한 메시지가 출력된다.

[ 실행 - morgan 미들웨어 토큰 ]

  • 웹 브라우저로 http://127.0.0.1:52273 을 3번 호출했다.
  • :method 로 GET 요청인지 POST 요청인지 출력한다.
  • :date 로 웹 브라우저로 요청한 시간을 출력한다.


[ morgan 미들웨어의 기본 형식 ]

  • default        :default-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":User-Agent"
  • short          :remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms
  • tiny           :method :url :status :res[content-length] - :response-time ms


[ 코드 - morgan 미들웨어 기본 형식 ]

//모듈을 추출한다.

var http = require('http');

var express = require('express');

var morgan = require('morgan');


//서버를 생성한다.

var app = express();


//미들웨어를 설정한다.

app.use(morgan('short'));

app.use(function (request, response) {

    response.send('<h1>express Basic</h1>');

});


//서버를 실행한다.

http.createServer(app).listen(52273, function () {

    console.log('Server running at http://127.0.0.1:52273');

});


[ 실행 - morgan 미들웨어 기본 형식 ]

  • short의 형식인 :remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms 로 출력된다.

6. static 미들웨어
  • static 미들웨어는 웹 서버에서 손쉽게 파일을 제공하는 방법을 제공한다.

[ 코드 - static 미들웨어 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var morgan = require('morgan');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(morgan('combined'));
app.use(express.static(__dirname + '/public'));
app.use(function (request, response) {
    //응답한다.
    response.writeHead(200, {'Content-Type' : 'text/html'});
    response.end('<img src="/Node.js logo.png" width="100%" />');
})

//서버를 실행한다.
http.createServer(app).listen(52273, function() {
    console.log('Server running at http://127.0.0.1:52273');
});
  • public 폴더를 생성하여 그림 파일, 자바스크립트 파일, CSS 파일 등을 넣는다. 여기에서는 그림 파일을 넣었다.
  • 전역변수 __dirname을 사용하여 폴더 위치를 지정하면 나머지는 express 모듈이 전부 알아서 해준다.
  • static 미들웨어를 사용하면 지정한 폴더에 있는 내용을 모두 웹 서버 루트 폴더에 올린다.
  • 따라서 img 태그의 src 속성에 "/public"이 아닌 바로 이미지 파일명을 입력하여 사용했다.
[ 실행 - static 미들웨어 ]

  • 지정한 이미지 파일이 출력된 것을 확인할 수 있다.

7. router 미들웨어
  • router 미들웨어는 페이지 라우팅을 구현하는 미들웨어이다.
  • 페이지 라우팅은 클라이언트 요청에 적절한 페이지를 제공하는 기술이다.
  • app.router 속성을 사용하고 다른 미들웨어와 다르게 express 객체에 들어있는 것이 아니고 함수를 호출하는 것이 아니다.
[ 코드 - router 미들웨어 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var morgan = require('morgan');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(morgan('combined'));
app.use(app.router);

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});

[ app 객체의 메서드 ]
  • get(path, callback)        GET 요청이 발생했을 때의 이벤트 리스너를 지정한다.
  • post(path, callback)       POST 요청이 발생했을 때의 이벤트 리스너를 지정한다.
  • put(path, callback)       PUT 요청이 발생했을 때의 이벤트 리스너를 지정한다.
  • del(path, callback)        DELETE 요청이 발생했을 때의 이벤트 리스너를 지정한다.
  • all(path, callback)        모든 요청이 발생했을 때의 이벤트 리스너를 지정한다.

[ 코드 - app 객체의 메서드 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var morgan = require('morgan');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(morgan('combined'));
//app.use(app.router); //express 4.x 부터 사용되지 않는다. 바로 get() 또는 post()로 사용한다.
app.use(express.static(__dirname + '/public'));

//라우터를 설정한다.
app.get('/a', function (request, response) {
    response.send('<a href="/b">Go to B</a>');
});
app.get('/b', function (request, response) {
    response.send('<a href="/a">Go to A</a>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});

[ 실행 - router 모듈의 기본적인 사용 결과 ]

  • http://127.0.0.1:52273/a 로 접근했을 때의 화면이다.

  • http://127.0.0.1:52273/b 로 접근했을 때의 화면이다.

  • http://127.0.0.1:52273/a 와 http://127.0.0.1:52273/b 로 접근했을 때 출력된 로그이다.

[ 코드 - router 모듈의 매개변수 추출 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var morgan = require('morgan');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(morgan('combined'));
//app.use(app.router); //express 4.x버전부터 사용하지 않는다.

//라우터를 설정한다.
app.get('/page/:id', function (request, response) {
    //변수를 선언한다.
    var name = request.param('id');

    //응답한다.
    response.send('<h1>' + name + ' Page</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});
  • get() 메서드의 첫 번째 매개변수에 문자열 /:id 를 입력했다.
  • http://127.0.0.1:52273/page/273 에 접속하면 id 속성에 273을 입력했으므로 '273 Page'를 출력한다.
[ 실행 - 매개변수 출력 ]


[ 코드 - 전체 선택자 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var morgan = require('morgan');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
//app.use(app.router); //express 4.x부터 사용되지 않는다.

//라우터를 설정한다.
app.get('/index', function (request, response) {
    response.send('<h1>Index Page</h1>');
});

app.all('*', function (request, response) {
    response.send(404, '<h1>ERROR - Page Not Found</h1>');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});
  • http://127.0.0.1:52273/index 이외의 요청은 모두 에러를 출력한다.
[ 실행 - 정상 출력 ]

  • http://127.0.0.1:52273/index 로 접근했을 때의 화면이다.
[ 실행 - 오류 출력 ]

  • http://127.0.0.1:52273/index 이외에 다른 주소로 접근했을 때의 오류 화면이다. ex) http://127.0.0.1:52273/test

8. cookie parser 미들웨어
  • cookie parser 미들웨어는 요청 쿠키를 추출하는 미들웨어이다.
  • cookie parser 미들웨어를 사용하면 request 객체에 cookies 속성이 부여된다.
[ 코드 - cookie parser 미들웨어 ]
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var cookieParser = require('cookie-parser'); //express 4.x부터 express.cookieParser()가 사용되지 않으므로 이것으로 사용한다.

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
//app.use(express.cookieParser()); //express 4.x부터 사용하지 않는다.
//app.use(app.router); //express 4.x부터 사용하지 않는다.
app.use(cookieParser()); //express 4.x부터 express.cookieParser()가 사용되지 않으므로 이것으로 사용한다.

//서버를 실행한다.
http.createServer(app).listen(52273, function (request, response) {
    console.log('Server running at http://127.0.0.1:52273');
});
  • require('cookie-parser') 를 사용하기 위해서는 모듈을 설치해야 한다.
[ cookie-parser 모듈 설치 ]
$ npm install cookie-parser


[ 코드 - cookie parser 미들웨어를 사용한 쿠키 추출 ]

//모듈을 추출한다.

var http = require('http');

var express = require('express');

var cookieParser = require('cookie-parser'); //express 4.x부터 express.cookieParser()가 사용되지 않으므로 이것으로 사용한다.


//서버를 생성한다.

var app = express();

//app.use(app.router); //express 4.x부터 사용되지 않는다.

app.use(cookieParser()); //express 4.x부터 express.cookieParser()가 사용되지 않으므로 이것으로 사용한다.


//라우터를 설정한다.

app.get('/getCookie', function (request, response) {

    //응답한다.

    response.send(request.cookies);

});

app.get('/setCookie', function (request, response) {

    //쿠키를 생성한다.

    response.cookie('string', 'cookie');

    response.cookie('json', {

        name: 'cookie',

        property: 'delicious'

    });


    //응답한다.

    response.redirect('/getCookie');

});


//서버를 실행한다.

http.createServer(app).listen(52273, function () {

    console.log('Server running at http://127.0.0.1:52273');

});

  • http://127.0.0.1:52273/setCookie 로 접속하면 string 쿠키와 json 쿠키를 생성한다.
  • 이어서 redirect로 getCookie로 자동 이동한다.
[ 실행 - cookie parser 미들웨어 ]


[ cookie() 메서드의 세 번째 매개변수 ]
response.cookie('string', 'cookie', {
maxAge: 6000,
secure: true
});

[ cookie() 메서드의 옵션 속성 ]
  • httpOnly : 클라이언트의 쿠키 접근 권한을 지정한다.
  • secure : secure 속성을 지정한다.
  • expires : expires 속성을 지정한다.
  • maxAge : 상대적으로 expires 속성을 지정한다.
  • path : path 속성을 지정한다.


9. body parser 미들웨어

  • POST 요청 데이터를 추출하는 미들웨어이다.
  • body parser 미들웨어를 사용하면 request 객체에 body 속성이 부여된다.
  • express 4.x부터 body parser가 사용되지 않으므로 body-parser 미들웨어를 설치해야 한다.

[ body-parser 미들웨어 설치 ]
$ npm install body-parser


9.1 입력 양식 데이터 추출

[ 코드 - login.html 파일 ]

<!DOCTYPE html>

<html>

<head>

    <title>Login Page</title>

</head>

<body>

    <h1>Login Page</h1>

    <hr />

    <form method="post">

        <table>

            <tr>

                <td><label>Username</label></td>

                <td><input type="text" name="login" /></td>

            </tr>

            <tr>

                <td><label>Password</label></td>

                <td><input type="password" name="password" /></td>

            </tr>

        </table>

        <input type="submit" name="" />

    </form>

</body>

</html>


[ 코드 - 서버 기본 설정 ]

//모듈을 추출한다.

var fs = require('fs');

var http = require('http');

var express = require('express');

var cookieParser = require('cookie-parser');

var bodyParser = require('body-parser');


//서버를 생성한다.

var app = express();


//미들웨어를 설정한다.

app.use(cookieParser());


//라우터를 설정한다.

app.get('/', function (request, response) { });

app.get('/login', function (request, response) { });

app.post('/login', function (request, response) { });


//서버를 실행한다.

http.createServer(app).listen(52273, function () {

    console.log('Server running at http://127.0.0.1:52273');

})

  • 이어서 GET 방식으로 여청했을 경우 POST 방식으로 요청했을 경우 두 가지로 나누어 GET 방식일 때는 HTML 페이지를 추출하고 POST 방식일 때는 클라이언트가 입력한 아이디와 비밀번호를 확인하여 auth 쿠키를 생성하는 것을 만들어보자.
[ 코드 - 기본적인 로그인 구현 ]
//모듈을 추출한다.
var fs = require('fs');
var http = require('http');
var express = require('express');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(cookieParser());
app.use(bodyParser());

//라우터를 설정한다.
app.get('/', function (request, response) {
    if (request.cookies.auth) {
        response.send('<h1>Login Success</h1>');
    } else {
        response.redirect('/login');
    }
});
app.get('/login', function (request, response) {
    fs.readFile('login.html', function (error, data) {
        response.send(data.toString());
    });
});
app.post('/login', function (request, response) {
    //쿠키를 생성한다.
    var login = request.param('login');
    var password = request.param('password');

    //출력한다.
    console.log(login, password);
    console.log(request.body);

    //로그인을 확인한다.
    if (login == 'rint' && password == '1234') {
        //로그인 성공
        response.cookie('auth', true);
        response.redirect('/');
    } else {
        //로그인 실패
        response.redirect('/login');
    }
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
})

[ 실행 - 로그인 화면 ]

  • Username 과 Password에 아무 글자나 입력하면 다시 로그인 화면으로 돌아온다.
  • Username에 rint 를, password에 1234 를 입력하고 [제출] 버튼을 클릭한다.

[ 실행 - 로그인 성공 화면 ]



9.2 파일 업로드
  • 일반적인 입력 양식은 application/x-www-from-urlencoded 인코딩 방식을 사용한다.
  • 파일은 일반적인 입력 양식 데이터에 비해 용량이 크다. 따라서 웹 브라우저는 파일을 전송할 때 multipart/form-data 인코딩 방식을 사용한다.
  • express 4.x부터 multipart 미들웨어가 제거되어 bodyParser 미들웨어의 multipart 기능이 불가능해졌다.
  • 그렇기 때문에 대체수단으로 connect-multipart 미들웨어를 설치한다.

[ connect-multipart 미들웨어 설치 ]
$ npm install connect-multiparty
 
[ 코드 - HTMLPage.html 파일 ]
<!DOCTYPE html>
<html>
<head>
    <title>Multipart Upload</title>
</head>
<body>
    <h1>File Upload</h1>
    <form method="post" enctype="multipart/form-data">
        <table>
            <tr>
                <td>Comment: </td>
                <td><input type="text" name="comment" /></td>
            </tr>
            <tr>
                <td>File: </td>
                <td><input type="file" name="image" /></td>
            </tr>
        </table>
        <input type="submit" />
    </form>
</body>
</html>
  • 반드시 <form> 태그의 enctype 속성을 "multipart/form-data"로 지정해야 한다.
[ 코드 - 미들웨어 설정 ]
//모듈을 추출한다.
var fs = require('fs');
var http = require('http');
var express = require('express');
var multiparty = require('connect-multiparty'); //express 4.x 부터 express 모듈의 multipart 미들웨어가 제거되었다. 따라서 bodyParser 미들웨어에서 multipart 기능(업로드와 form-data 파싱)이 불가능해져서 이 미들웨어를 설치하여 사용한다.
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(cookieParser());
//app.use(express.limit('10mb')); //express 4.x 부터 사용되지 않는다. 아래 문장처럼 사용할 것.
app.use(bodyParser.json({ limit : '10mb' }));
//app.use(bodyParser({ uploadDir : __dirname + '/multipart' }));
app.use(multiparty({ uploadDir : __dirname + '/multipart' }));
//app.use(app.router); //express 4.x 부터 사용되지 않는다. 바로 get() 또는 post()로 사용한다.

//라우터를 설정한다.
app.get('/', function (request, response) {
    fs.readFile('HTMLPage.html', function (error, data) {
        response.send(data.toString());
    });
});
app.post('/', function (request, response) {
    console.log(request.body);
    console.log(request.files);

    response.redirect('/');
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});


[ 실행 - 파일 업로드 ]


[ 실행 - 파일 업로드 ]

  • 업로드한 파일의 정보가 출력된다.

[ 코드 - 파일 이름 변경 및 제거 ]

//모듈을 추출한다.

var fs = require('fs');

var http = require('http');

var express = require('express');

var multiparty = require('connect-multiparty'); //express 4.x 부터 express 모듈의 multipart 미들웨어가 제거되었다. 따라서 bodyParser 미들웨어에서 multipart 기능(업로드와 form-data 파싱)이 불가능해져서 이 미들웨어를 설치하여 사용한다.

var cookieParser = require('cookie-parser');

var bodyParser = require('body-parser');


//서버를 생성한다.

var app = express();


//미들웨어를 설정한다.

app.use(cookieParser());

app.use(multiparty());

app.use(express.static('public'));

//app.use(express.limit('10mb')); //express 4.x 부터 사용되지 않는다. 아래 문장처럼 사용할 것.

app.use(bodyParser.json({ limit : '10mb' }));

app.use(bodyParser({ uploadDir : __dirname + '/multipart' }));

//app.use(app.router); //express 4.x 부터 사용되지 않는다. 바로 get() 또는 post()로 사용한다.


//라우터를 설정한다.

app.get('/', function (request, response) {

    fs.readFile('HTMLPage.html', function (error, data) {

        response.send(data.toString());

    });

});

app.post('/', function (request, response) {

    var comment = request.param('comment');

    var imageFile = request.files.image;


    if (imageFile) {

        //변수를 선언한다.

        var name = imageFile.name;

        var path = imageFile.path;

        var type = imageFile.type;


        //이미지 파일 확인

        if (type.indexOf('image') != -1) {

            //이미지 파일의 경우: 파일의 이름을 변경한다.

            var outputPath = __dirname + '/multipart/' + Date.now() + '_' + name;


            fs.rename(path, outputPath, function (error) {

                response.redirect('/');

            });

        } else {

            //이미지 파일이 아닌 경우: 파일 이름을 제거한다.

            fs.unlink(path, function (error) {

                response.send(400);

            });

        }

    } else {

        //파일이 없을 경우

        response.send(404);

    }

});


//서버를 실행한다.

http.createServer(app).listen(52273, function () {

    console.log('Server running at http://127.0.0.1:52273');

});

  • 파일 업로드 할 때 파일명이 같은 경우 덮어 씌워지게 된다. 따라서 파일명을 확인하여 중복되지 않도록 하고자 한다.
  • rename() 메서드를 사용해 시간을 기반으로 파일의 이름을 변경한다.(이 방식이 100% 중복을 막을 수 없으나 예제로 하겠다.)
  • 또한 이미지 파일이 아니라면 파일을 제거한다.
  • 웹브라우저로 실행하여 파일을 업로드하면 multipart 디렉터리에 "날짜_파일명.확장자"와 같은 형식으로 이름이 바뀌어 업로드된 것을 확인할 수 있다.


10. session 미들웨어

  • 쿠키(cookie)는 정보를 클라이언트의 PC에 저장하고 세션(session)은 정보를 서버에 저장하는 기술이다.
  • 세션은 클라이언트에 세션 식별자 쿠키를 부여한다.
  • 부여한 세션 식별자 쿠키와 대응되는 서버에 위치하는 별도 저장소에 데이터를 저장한다.
  • session 미들웨어는 세션을 쉽게 생성할 수 있게 도와주는 미들웨어이다.
  • session 미들웨어를 사용하면 request 객체에 session 속성을 부여한다.
  • session 미들웨어는 자체적으로 cookie parser 미들웨어를 사용하므로 cookie-parser 미들웨어와 session 미들웨어가 순서대로 추가되어야 한다.
  • express 4.x부터 express.session()이 지원되지 않으므로 cookie-session 미들웨어를 설치한다.


[ cookie-session 미들웨어 설치 ]

$ npm install cookie-session


[ 코드 - session 미들웨어 ]

//모듈을 추출한다.

var http = require('http');

var express = require('express');

var cookieParser = require('cookie-parser');

var session = require('cookie-session');

var bodyParser = require('body-parser');


//서버를 실행한다.

var app = express();


//미들웨어를 설정한다.

app.use(cookieParser());

app.use(session({ secret: 'secret key' }));

app.use(bodyParser());

app.use(function (request, response) {

    //변수를 선언한다.

    var output = {};

    output.cookies = request.cookies;

    output.session = request.session;


    //세션을 저장한다.

    request.session.now = (new Date()).toUTCString();


    //응답한다.

    response.send(output);

});


//서버를 실행한다.

http.createServer(app).listen(52273, function () {

    console.log('Server running at http://127.0.0.1:52273');

});


[ 실행 - 처음 접속 ]

  • session에 저장된 내용만 출력된다. cookie 정보는 다시 접속했을 때 나타나게 된다.


[ 실행 - 두 번째 접속 ]

  • 다시 접속하면 cookies의 express:sess.sig 쿠키가 생성된 것을 확인할 수 있다. 이것은 쿠키로 서버에 저장된 데이터를 확인한다.
  • 브라우저를 종료하고 다시 실행하면 express:sess.sig 쿠키가 소멸되므로 클라이언트는 자신이 소유한 정보를 잃게 된다.

[ 코드 - session() 메서드의 옵션 ]
  • session의 이름과 유지하는 시간을 바꾸어보자.
//모듈을 추출한다.
var http = require('http');
var express = require('express');
var cookieParser = require('cookie-parser');
var session = require('cookie-session');
var bodyParser = require('body-parser');

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(cookieParser());
app.use(session({
    secret: 'secret key',
    key: 'rint',
    cookie: {
        maxAge: 60 * 1000
    }
}));
app.use(bodyParser());
app.use(function (request, response) {
    //변수를 선언한다.
    var output = {};
    output.cookies = request.cookies;
    output.session = request.session;

    //세션을 저장한다.
    request.session.now = (new Date()).toUTCString();

    //응답한다.
    response.send(output);
});

//서버를 실행한다.
http.createServer(app).listen(52273, function () {
    console.log('Server running at http://127.0.0.1:52273');
});



[ session() 메서드의 옵션 ]

  • key : 쿠키의 name 속성을 지정한다.
  • store : 세션 저장소를 지정한다.
  • cookie : 생성할 cookie와 관련된 정보를 지정한다.


[ cookie 속성을 입력하지 않으면 다음과 같은 객체가 입력된다.

{ path: '/', httpOnly: true, maxAge: null }


[ session 객체의 메서드 ]

  • regenerate() : 세션을 다시 생성한다.
  • destroy() : 세션을 제거한다.
  • reload() : 세션을 다시 불러온다.
  • save() : 세션을 저장한다.



11. RESTful 웹 서비스 개발

  • RESTful 웹 서비스는 REST(REpresentational Status Transfer) 규정에 맞춰 만든 웹 서비스를 의미한다.
  • REST 규정이란?
    • 일관된 웹 서비스 인터페이스 설계를 위한 규정이다.
[ RESTful 웹 서비스의 구조 ]

 경로

 /collection

 collection 

 GET 방식

 컬렉션을 조회한다.

 컬렉션의 특정 요소를 조회한다. 

 POST 방식

 컬렉션에 새로운 데이터를 추가한다.

 사용하지 않는다.

 PUT 방식

 컬렉션 전체를 한꺼번에 변경한다.

 컬렉션에 특정 요소를 수정한다.

 DELETE 방식

 컬렉션 전체를 삭제한다.

 컬렉션의 특정 요소를 삭제한다.


[ 예제 ]
  • GET /user - 사용자 전체를 조회한다.
  • GET /user/273 - 273번 사용자를 조회한다.
  • POST /user - 사용자를 추가한다.
  • DELETE /user/273 - 273번 사용자를 삭제한다.


[ RESTful 웹 서비스 ]

 라우트

 경로

 설명

 GET

 /user

 모든 사용자 정보를 조회한다.

 GET

 /user/:id

 특정 사용자 정보를 조회한다.

 POST

 /user

 사용자를 추가한다.

 PUT

 /user/:id

 특정 사용자 정보를 수정한다.

 DELETE

 /user/:id

 특정 사용자 정보를 제거한다.



[ 코드 - 시작 코드 ]
//모듈을 추출한다.
var fs = require('fs');
var http = require('http');
var express = require('express');
var bodyParser = require('body-parser');

//더미 데이터베이스를 구현한다.
var DummyDB = (function () {

})();

//서버를 생성한다.
var app = express();

//미들웨어를 설정한다.
app.use(bodyParser());

//라우터를 설정한다.
app.get('/user', function (request, response) { });
app.get('/user/:id', function (request, response) { });
app.post('/user', function (request, response) { });
app.put('/user/:id', function (request, response) { });
app.del('/user/:id', function (request, response) { });

//서버를 실행한다.
http.createServer(app).listen(52283, function () {
    console.log('Server running at http://127.0.0.1:52273');
});



11.1 더미 데이터베이스 구현

  • 데이터를 저장하려면 데이터 저장소가 필요하다.
  • 일반적으로 MySQL 같은 데이터베이스를 사용하지만 아직 배우지 않았으므로 더미 데이터베이스라는 가상의 데이터베이스를 만들어서 사용하자.
[ 코드 - DummyDB ]
//더미 데이터베이스를 구현한다.
var DummyDB = (function () {
    //변수를 선언한다.
    var DummyDB = {};
    var storage = {};
    var count = 1;

    //메서드를 구현한다.
    DummyDB.get = function (id) {
        if (id) {
            //변수를 가공한다.
            id = (typeof id == 'string') ? Number(id) : id;

            //데이터를 선택한다.
            for (var i in storage) if (storage[i].id == id) {
                return storage[i];
            }
        } else {
            return storage;
        }
    };

    DummyDB.insert = function (data) {
        data.id = count++;
        storage.push(data);
        return data;
    };

    DummyDB.remove = function (id) {
        //변수를 가공한다.
        id = (typeof id == 'string') ? Number(id) : id;

        //제거한다.
        for (var i in storage) if (storage[i].id == id) {
            //데이터를 제거한다.
            storage.splice(i, 1);

            //리턴한다 : 데이터 삭제 성공
            return true;
        }

        //리턴한다 : 데이터 삭제 실패
        return false;
    };

    //리턴한다.
    return DummyDB;
})();

  • get() 메서드
    • 데이터를 조회하는 메서드이다.
    • 매개변수 id를 넣고 호출하면 특정 데이터 하나를 선택해서 리턴한다.
    • 반면 id를 넣지 않고 호출하면 모든 데이터를 리턴한다.
  • insert() 메서드
    • 데이터를 추가하는데 사용한다.
    • 데이터에 id 속성을 추가하고 storage 배열에 넣는다.
    • 모든 처리가 정상적으로 완료되면 자기 자신을 리턴한다.
  • remove() 메서드
    • 데이터를 제거하는 메서드이다.
    • 배열의 splice() 메서드를 사용해 특정 데이터를 제거한다.


11.2 GET 요청

[ 코드 - GET 요청 ]

app.get('/user', function (request, response) {

    response.send(DummyDB.get());

});

app.get('/user/:id', function (request, response) {

    response.send(DummyDB.get(request.param('id')));

});

  • 모든 사용자를 조회하는 것과 특정 사용자를 조회하는 것을 구현한 것이다.
  • http://127.0.0.1:52273/user 에 접속한다. 아직 데이터를 넣지 않았으므로 아무 데이터도 출력되지 않는다.

11.3 POST 요청

[ 코드 - POST 요청 ]

app.post('/user', function (request, response) {

    //변수를 선언한다.

    var name = request.param('name');

    var region = request.param('region');


    //유효성을 검사한다.

    if (name && region) {

        response.send(DummyDB.insert({

            name: name,

            region: region

        }));

    } else {

        throw new Error('error');

    }

});

  • 입력 양식으로부터 전달된 name 속성과 region 속성을 추출하고 더미 데이터베이스에 추가한다.

[ 실행 - POST 요청 ]


  • 크롬 확장프로그램인 Postman 으로 실행한 모습이다.
  • 어떤 이유인지는 알 수 없으나 [form-data]로 하면 에러가 발생된다. 이부분 때문에 몇일동안 검색도 많이 해봤으나 해결하진 못했다.
  • [x-www-form-urlencoded]로 선택하여 진행하면 정상적으로 나온다. 파라미터 값에 한글을 입력한 것도 아닌데 왜 urlencode로 넘겨야 정상적으로 작동하는 것인지 이유는 모르겠다. ㅜ_ㅜ;;;
  • name, region, id 값이 정상적으로 DummyDB에 등록되어 화면에 출력된 모습을 볼 수 있다.

11.4 PUT 요청

  • id 속성과 name 속성, region 속성을 추출하고 더미 데이터베이스에서 데이터를 추출해 수정한다.
[ 코드 - PUT 요청 ]
app.put('/user/:id', function (request, response) {
    //변수를 선언한다.
    var id = request.param('id');
    var name = request.param('name');
    var region = request.param('region');

    //데이터베이스를 수정한다.
    var item = DummyDB.get(id);
    item.name = name || item.name;
    item.region = region || item.region;

    //응답한다.
    response.send(item);
});



[ 실행 - PUT 요청 ]


  • 앞서 POST 요청에서처럼 테스트한 뒤 PUT 요청을 사용하여 DummyDB를 수정해본다.

11.5 DELETE 요청
[ 코드 - DELETE 요청 ]
app.del('/user/:id', function (request, response) {
    response.send(DummyDB.remove(request.param('id')));
});


[ 실행 - DELETE 요청 ]

  • id가 1인 데이터에 대해 삭제를 하였다.




'Node.js' 카테고리의 다른 글

Node.js express 4.x 프레임워크 설치 및 실행  (0) 2016.02.11
Node.js 외부 모듈  (0) 2014.11.12
Node.js http 모듈  (0) 2014.11.05
Node.js 이벤트  (0) 2014.07.06
Node.js 기본 내장 모듈  (2) 2014.06.29