출처 : http://cafe.daum.net/program-db/cFz8/20?q=node.js%20express
- http 모듈로 웹 서버를 생성하면 굉장히 많은 일을 직접 처리해야 한다.
- express 모듈은 http 모듈에 여러 기능을 추가해 쉽게 사용할 수 있게 마든 모듈이다.
[ 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®ion=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 모듈 설치 ]
[ 코드 - 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-addd - :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-addd - :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.get('/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(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) {
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 요청 ]