웹 서버 만들기 5장 Do it! Node.js 프로그래밍 이지스퍼블리싱 제공 강의 교안 2017/03

Slides:



Advertisements
Similar presentations
Term Project Hints Topics Keep-alive CGI Multi-thread Multi-process Event-based.
Advertisements

박승제 웹 애플리케이션 기술 박승제
XHTML Basic 제 13 장 1. XHTML Basic의 개요 2. XHTML Basic 기본 문법 3. 표 만들기
W3000 제 품 제 안 서.
11 JSTL 사용하기.
Spring MVC ㅇ 스프링 MVC 구성요소 설명 DispatcherServlet 클라이언트의 요청을 컨트롤러에게 전달하고
IoT(사물인터넷) 보안 2016년 2학기 4. 라즈베리파이 카메라.
웹 프로그래밍 HTML, 자바스크립트, ASP를 중심으로
Introduction to Django
MEAN Stack Front to Back (MEANAuthApp)
2002/3/20 HTML 2002/3/20
웹 2.0 및 Ajax 개요.
IoT(사물인터넷) 보안 2016년 2학기 3. 라즈베리파이와 node.js.
Python Bottle Web Framework
12장. JSP에서 자바빈 활용 제12장.
7. JavaBeans 프로그래밍 JavaBeans JavaBeans 만들기 빈을 이용한 회원가입 양식 작성하기 빈 작성
채팅 서버 만들기 10장 Do it! Node.js 프로그래밍 이지스퍼블리싱 제공 강의 교안 2017/03
모바일 서버 만들기 13장 Do it! Node.js 프로그래밍 이지스퍼블리싱 제공 강의 교안 2017/03
Chapter 32 Analyzing Web Traffic
2 서블릿의 기초.
9장. 요청 흐름제어와 모듈화 #1: <jsp:forward> 액션태그 사용
10장. 에러 처리 제10장.
JSP 내장 객체 개요 내장 객체 (참조 변수 이름) 자바 클래스 주요 역할
01. Index StarPlayer API Guide 01. Index 02. 상수값 정의 03. API 정의
Chapter 04. 웹 보안 : 웹, 그 무한한 가능성과 함께 성장한 해킹
Web Server와 DB 연동.
APM (Apache+PHP+MySQL)
이 름: 정홍도 (과장) 팀 명: 개발사업팀 일 자:
위치기반서비스 서버 만들기 12장 Do it! Node.js 프로그래밍 이지스퍼블리싱 제공 강의 교안 2017/03
4 쿠키와 세션.
ㅎㅎ 파일업로드와 이메일 발송 HTTP 파일 업로드와 탭스 업로드 컴포넌트 데이터베이스 연동 자료실 만들기
데이터베이스 사용하기 6장 Do it! Node.js 프로그래밍 이지스퍼블리싱 제공 강의 교안 2017/03
Chapter 02 웹의 이해.
node.js, express, jade, mongodb를 이용한 웹 어플리케이션 개발
중 간 고 사 (웹프로그래밍)
AJAX 커머스아이 박준열.
게시판 만들기 14장 Do it! Node.js 프로그래밍 이지스퍼블리싱 제공 강의 교안 2017/03
JSON-RPC 서버 만들기 11장 Do it! Node.js 프로그래밍 이지스퍼블리싱 제공 강의 교안 2017/03
웹서버와 설치에 필요한 것 WWW ( world wide web ) TCP/IP 프로토콜을 이용하는 클라이언트/서버 환경
5. JSP의 내장객체1.
6부 WML/WML2.0 언어배우기 6-1 WML에 대해서 6-2 WML 기본 태그 6-3 글과 그림 삽입에 관련된 태그
MEAN Stack Front to Back (MEANAuthApp)
8 데이터베이스 사용하기.
12 데이터베이스 사용하기.
웹 어플리케이션 보안 2016년 2학기 4. Restful node apI 만들기.
뷰 템플릿 적용하기 8장 Do it! Node.js 프로그래밍 이지스퍼블리싱 제공 강의 교안 2017/03
Cookie 와 Session.
Network Security WireShark를 활용한 프로토콜 분석 II.
BIZSIREN 실명확인서비스 개발 가이드 서울신용평가정보㈜ 신용조회부 (TEL , FAX )
HTML.
Chapter11 웹 스토리지 & 웹 데이터베이스
웹 어플리케이션 보안 2016년 2학기 2. Node routing.
JavaScript COOKIE Chapter 10 Part III
Web Vulnerabilities 정보 보호 2008/05/31 Getroot.
CGI (Common Gateway Interface)
SNS 로그인 API 연동 조휘제.
HTML CSS 자바스크립트 무작정 따라하기
상품등록 방식 비교 년 4월 23일 (주)에이치케이넷츠.
KTF 무선인터넷 표준 UI 2000년 4월 SK 텔레콤 귀중 CP 제공용
Chapter13 파일 접근 & 오프라인 접근 HTML5 Programming.
IoT(사물인터넷) 보안 2016년 2학기 3. 라즈베리파이와 node.js.
CGI (Common Gateway Interface)
ASP 수행 화면(1).
노드로 만들 수 있는 대표적인 서버와 용도 준비마당 Do it! Node.js 프로그래밍 이지스퍼블리싱 제공 강의 교안
LOGIN할 때 아이디, 비번 입력 여부 체크하기
세션 (Session) Yang-Sae Moon Department of Computer Science
주요공지로 정할 글을 올립니다. 제목과 주소를 복사해둡니다
웹 스크래핑.
Data Base Web Programming
MEAN Stack Front to Back (MEANAuthApp)
Presentation transcript:

웹 서버 만들기 5장 Do it! Node.js 프로그래밍 이지스퍼블리싱 제공 강의 교안 2017/03 ○ 본 강의 자료는 이지스퍼블리싱에서 제공하는 강의 교안입니다. ○ 본 강의 교안은 아래 출판 서적의 내용을 기준으로 구성되었습니다. 또한 다수의 기타 서적이나 사이트를 참조하였습니다. 레퍼런스를 참조하십시오. 2017, 정재곤, “Do it! Node.js 프로그래밍 (개정판)”, 이지스퍼블리싱 - 강의 교안에 사용된 화면 캡처나 실습 자료의 경우에는 문서 업데이트에 따라 변경될 수 있습니다.

강의 주제 및 목차 웹 서버 만들기 강의 주제 목 차 간단한 웹 서버 만들기 익스프레스로 웹 서버 만들기 미들웨어 사용하기 목 차 1 간단한 웹 서버 만들기 2 익스프레스로 웹 서버 만들기 3 미들웨어 사용하기 4 요청 라우팅하기 5 쿠키와 세션 관리하기 6 파일 업로드 기능 만들기

1. 간단한 웹 서버 만들기 난이도 소요시간 30분

http 모듈로 웹 서버 시작 var http = require('http'); var server = http.createServer(); var port = 3000; server.listen(port, function() { console.log('웹 서버가 시작되었습니다. : %d', port); });

http 모듈로 웹 서버를 실행하는 과정 createServer() 메소드로 웹 서버 객체 만들고 listen() 메소드로 대기 메소드 이름 설명 listen(port[, hostname][, backlog][, callback] 서버를 실행하여 대기시킵니다. close([callback]) 서버를 종료합니다.

클라이언트가 요청할 때 발생하는 이벤트 처리 var host = '192.168.0.5'; var port = 3000; 웹 브라우저에서 요청할 때 상황에 따른 적절한 이벤트 발생 이벤트 이름 설명 connection 클라이언트가 접속하여 연결이 만들어질 때 발생하는 이벤트입니다. request 클라이언트가 요청할 때 발생하는 이벤트입니다. close 서버를 종료할 때 발생하는 이벤트입니다. 웹 서버 실행 시 호스트와 포트 지정하는 경우 var host = '192.168.0.5'; var port = 3000; server.listen(port, host, '50000', function() { console.log('웹 서버가 시작되었습니다. : %s, %d', host, port); });

클라이언트가 요청할 때 발생하는 이벤트 처리 connection 이벤트와 request 이벤트 처리 var http = require('http'); var server = http.createServer(); var port = 3000; server.listen(port, function() { console.log('웹 서버가 시작되었습니다. : %d', port); }); server.on('connection', function(socket) { var addr = socket.address(); console.log('클라이언트가 접속했습니다. : %s, %d', addr.address, addr.port); server.on('request', function(req, res) { console.log('클라이언트 요청이 들어왔습니다.'); console.dir(req);

정상 실행되는 경우와 이미 포트를 사용 중일 때의 오류 FADDRINUSE 에러 발생하는 경우 있음 – 기존 포트를 사용하고 있는 경우임

클라이언트로 응답 보내기 request 이벤트 처리할 때 writeHead(), write(), end() 메소드로 응답 전송 server.on('request', function(req, res) { console.log('클라이언트 요청이 들어왔습니다.'); res.writeHead(200, {"Content-Type": "text/html; charset=utf-8"}); res.write("<!DOCTYPE html>"); res.write("<html>"); res.write(" <head>"); res.write(" <title>응답 페이지</title>"); res.write(" </head>"); res.write(" <body>"); res.write(" <h1>노드제이에스로부터의 응답 페이지</h1>"); res.write(" </body>"); res.write("</html>"); res.end(); });

클라이언트로 응답을 보내는 방식 요청을 받으면 request 이벤트가 발생되고 write() 메소드 등을 이용해 응답 전송 메소드 이름 설명 writeHead(statusCode [, statusMessage][, headers] 응답으로 보낼 헤더를 만듭니다. write(chunk[, encoding][, callback]) 응답 본문(body) 데이터를 만듭니다. 여러 번 호출될 수 있습니다. end([data][, encoding][, callback]) 클라이언트로 응답을 전송합니다.

서버 객체를 만들면서 응답 처리를 할 수도 있음 실제로 많이 사용되지는 않음 (모든 요청을 한꺼번에 처리하는 경우는 거의 없기 때문) var server = http.createServer(function(req, res) { console.log('클라이언트 요청이 들어왔습니다.'); res.writeHead(200, {"Content-Type": "text/html; charset=utf-8"}); res.write("<!DOCTYPE html>"); res.write("<html>"); res.write(" <head>"); res.write(" <title>응답 페이지</title>"); res.write(" </head>"); res.write(" <body>"); res.write(" <h1>노드제이에스로부터의 응답 페이지</h1>"); res.write(" </body>"); res.write("</html>"); res.end(); });

클라이언트 요청이 있을 때 파일 읽어 응답하기 fs 모듈을 이용해 파일을 읽어 응답 보낼 수 있음 var http = require('http'); var fs = require('fs'); ……. server.on('request', function(req, res) { console.log('클라이언트 요청이 들어왔습니다.'); var filename = 'house.png'; fs.readFile(filename, function(err, data) { res.writeHead(200, {"Content-Type": "image/png"}); res.write(data); res.end(); });

파일을 읽어 응답을 보내는 방식 이미지 파일 이외에도 텍스트 파일이나 음악 파일 등을 보낼 수 있음

파일을 스트림으로 읽어 응답 보내기 createReadStream 으로 읽은 후 pipe() 메소드를 이용해 전송 server.on('request', function(req, res) { console.log('클라이언트 요청이 들어왔습니다.'); var filename = 'house.png'; var infile = fs.createReadStream(filename, {flags: 'r'} ); infile.pipe(res); });

파일을 버퍼에 담아두고 일부분만 읽어 응답 보내기 파일에서 read() 로 읽고 응답 객체의 write() 메소드를 이용해 응답 전송 res.writeHead(200, {"Content-Type": "image/png"}); infile.on('readable', function() { var chunk; while (null !== (chunk = infile.read())) { console.log('읽어 들인 데이터 크기 : %d 바이트', chunk.length); curlength += chunk.length; res.write(chunk, 'utf8', function(err) { console.log('파일 부분 쓰기 완료 : %d, 파일 크기 : %d', curlength, filelength); if (curlength >= filelength) { res.end(); } });

다른 웹사이트의 데이터 가져오기 http 모듈을 사용해 다른 웹사이트의 데이터를 가져와서 필요한 곳에 사용할 수 있음 var http = require('http'); var options = { host: 'www.google.com', port: 80, path: '/' }; var req = http.get(options, function(res) { var resData = ''; res.on('data', function(chunk) { resData += chunk; }); res.on('end', function() { console.log(resData); req.on('error', function(err) { console.log("에러 발생 : " + err.message);

다른 웹사이트의 데이터 가져오는 방식 POST 방식으로 요청할 때는 request() 메소드 사용 var resData = ''; var req = http.request(opts, function(res) { res.on('data', function(chunk) { resData += chunk; }); res.on('end', function() { console.log(resData);

2. 익스프레스로 웹 서버 만들기 난이도 소요시간 30분

새로운 익스프레스 서버 만들기 새로운 프로젝트 폴더를 ExpressExample로 만듬 파일>폴더 열기 메뉴를 눌러 프로젝트 폴더 지정 명령프롬프트에서 npm init 명령 실행하여 package.json 파일 생성 // 익스프레스 객체 생성 var app = express(); // 기본 포트를 app 객체에 속성으로 설정 app.set('port', process.env.PORT || 3000); // Express 서버 시작 http.createServer(app).listen(app.get('port'), function(){ console.log('익스프레스 서버를 시작했습니다 : ' + app.get('port')); });

익스프레스 객체 익스프레스 app 객체의 주요 메소드와 주요 속성 이름 메소드 이름 설명 set(name, value) 서버 설정을 위한 속성을 지정합니다. set( ) 메소드로 지정한 속성은 get( ) 메소드로 꺼내어 확인할 수 있습니다. get(name) 서버 설정을 위해 지정한 속성을 꺼내 옵니다. use([path,] function [, function...]) 미들웨어 함수를 사용하도록 합니다. get([path,] function) 특정 패스로 요청된 정보를 처리합니다. 속성 이름 설명 env 서버 모드를 설정합니다. views 뷰들이 들어 있는 폴더 또는 폴더 배열을 설정합니다. view engine 디폴트로 사용할 뷰 엔진을 설정합니다.

포트 설정 port 속성 설정 // 기본 포트를 app 객체에 속성으로 설정 app.set('port', process.env.PORT || 3000);

실행 Express 외장 모듈 설치하고 실행 % npm install express --save

미들웨어 사용하기 미들웨어는 중간에 요청을 처리하고 라우터는 요청 패스에 따라 분기하여 처리

미들웨어 직접 만들어보기 use() 메소드를 사용함 (Express 3 버전과 Express 4 버전의 코드가 다름에 주의함) var express = require('express') , http = require('http'); var app = express(); app.use(function(req, res, next) { console.log('첫 번째 미들웨어에서 요청을 처리함.'); res.writeHead('200', {'Content-Type':'text/html;charset=utf8'}); res.end('<h1>Express 서버에서 응답한 결과입니다.</h1>'); }); http.createServer(app).listen(3000, function() { console.log('Express 서버가 3000번 포트에서 시작됨.');

익스프레스에서 웹 서버를 만드는 가장 간단한 구성 app 객체를 만듬. use 메소드를 이용해 미들웨어를 등록함

여러 개의 미들웨어 사용하기 use() 메소드를 여러 번 사용함 app.use(function(req, res, next) { console.log('첫 번째 미들웨어에서 요청을 처리함.'); req.user = 'mike'; next(); }); app.use('/', function(req, res, next) { console.log('두 번째 미들웨어에서 요청을 처리함.'); res.writeHead('200', {'Content-Type':'text/html;charset=utf8'}); res.end('<h1>Express 서버에서 ' + req.user + '가 응답한 결과입니다.</h1>');

두 개의 미들웨어를 사용할 때의 구성 use() 메소드를 여러 번 사용하면서 다음 미들웨어로 넘길 때 next() 사용

익스프레스의 요청 객체와 응답 객체 익스프레스의 요청 객체와 응답 객체에는 메소드가 더 추가되어 있음. 메소드 이름 설명 send([body]) 클라이언트에 응답 데이터를 보냅니다. 전달할 수 있는 데이터는 HTML 문자열, Buffer 객체, JSON 객체, JSON 배열입니다. status(code) HTTP 상태 코드를 반환합니다. 상태 코드는 end( )나 send( ) 같은 전송 메소드를 추가로 호출해야 전송할 수 있습니다. sendStatus(statusCode) HTTP 상태 코드를 반환합니다. 상태 코드는 상태 메시지와 함께 전송됩니다. redirect([status,] path) 웹 페이지 경로를 강제로 이동시킵니다. render(view [, locals][, callback] 뷰 엔진을 사용해 문서를 만든 후 전송합니다. app.use(function(req, res, next) { console.log('첫 번째 미들웨어에서 요청을 처리함.'); res.send({name:'소녀시대', age:20}); });

응답 확인 브라우저에서 응답 확인 http://localhost:3000 또는 PC의 IP를 확인한 후 http://192.168.0.5:3000/과 같이 조회

redirect() 메소드로 다른 페이지로 이동하기 app.use(function(req, res, next) { console.log('첫 번째 미들웨어에서 요청을 처리함.'); res.redirect('http://google.co.kr'); });

익스프레스에서 요청 객체에 추가한 메소드 헤더를 확인하는 방법과 요청 파라미터를 확인하는 방법 (Express 4 기준) 추가한 정보 설명 query 클라이언트에서 GET 방식으로 전송한 요청 파라미터를 확인합니다. 예) req.query.name body 클라이언트에서 POST 방식으로 전송한 요청 파라미터를 확인합니다. 단, body-parser와 같은 외장 모듈을 사용해야 합니다. 예) req.body.name header(name) 헤더를 확인합니다.

헤더와 요청 파라미터 확인 파라미터를 전달하고 그 파라미터를 다시 응답으로 받을 수 있음 ……. app.use(function(req, res, next) { console.log('첫 번째 미들웨어에서 요청을 처리함.'); var userAgent = req.header('User-Agent'); var paramName = req.query.name; res.writeHead('200', {'Content-Type':'text/html;charset=utf8'}); res.write('<h1>Express 서버에서 응답한 결과입니다.</h1>'); res.write('<div><p>User-Agent : ' + userAgent + '</p></div>'); res.write('<div><p>Param name : ' + paramName + '</p></div>'); res.end(); });

요청한 파라미터를 확인하는 과정 파라미터를 전달하고 그 파라미터를 다시 응답으로 받을 수 있음 ▶ http://localhost:3000/?name=mike

3. 미들웨어 사용하기 난이도 소요시간 20분

static 미들웨어 var static = require('serve-static'); ... 특정 폴더의 파일들을 특정 패스로 접근할 수 있도록 열어주는 역할을 함 var static = require('serve-static'); ... app.use(static(path.join(__dirname, 'public'))); ExpressExample/public/index.html ExpressExample/public/images/house.png ExpressExample/public/css/style.css http://localhost:3000/index.html http://localhost:3000/images/house.png http://localhost:3000/css/style.css

static 미들웨어를 이용해 이미지 열어주는 방식 /images/house.png 와 같은 패스를 지정할 수 있음 res.end("<img src='/images/house.png' width='50%'"); app.use(‘/public’, static(path.join(__dirname, 'public')));

body-parser 미들웨어 사용하기 POST로 요청했을 때의 요청 파라미터 확인 방법 제공 ExpressExample 폴더 안에 있는 public 폴더 안에 login.html 파일 생성 … <form method="post"> <table> <tr> <td><label>아이디</label></td> <td><input type="text" name="id" /></td> </tr> <td><label>비밀번호</label></td> <td><input type="password" name="password" /></td> </table> <input type="submit" value="전송" name="" /> </form>

body-parser 미들웨어를 사용하는 코드 추가 require() 메소드를 이용해 모듈 로딩한 후 설정 // Express 기본 모듈 불러오기 var express = require('express') , http = require('http') , path = require('path'); // Express의 미들웨어 불러오기 var bodyParser = require('body-parser') , static = require('serve-static'); // 익스프레스 객체 생성 var app = express(); // 기본 속성 설정 app.set('port', process.env.PORT || 3000); // body-parser를 이용해 application/x-www-form-urlencoded 파싱 app.use(bodyParser.urlencoded({ extended: false })) // body-parser를 이용해 application/json 파싱 app.use(bodyParser.json()) app.use(static(path.join(__dirname, 'public'))); …

body-parser 미들웨어를 사용하는 코드 추가 미들웨어에서 파라미터 확인 후 응답 전송 … // 미들웨어에서 파라미터 확인 app.use(function(req, res, next) { console.log('첫번째 미들웨어에서 요청을 처리함.'); var paramId = req.body.id || req.query.id; var paramPassword = req.body.password || req.query.password; res.writeHead('200', {'Content-Type':'text/html;charset=utf8'}); res.write('<h1>Express 서버에서 응답한 결과입니다.</h1>'); res.write('<div><p>Param id : ' + paramId + '</p></div>'); res.write('<div><p>Param password : ' + paramPassword + '</p></div>'); res.end(); });

body-parser 미들웨어 설치 후 실행 npm으로 설치 % npm install body-parser --save

4. 요청 라우팅하기 난이도 소요시간 20분

Router 사용해 요청 라우팅하기 var router = express.Router(); Router 객체를 참조한 후 route() 메소드를 이용해 라우팅 var router = express.Router(); router.route('/process/login').post(function(req, res) { 메소드 이름 설명 get(callback) GET 방식으로 특정 패스 요청이 발생했을 때 사용할 콜백 함수를 지정합니다. post(callback) POST 방식으로 특정 패스 요청이 발생했을 때 사용할 콜백 함수를 지정합니다. put(callback) PUT 방식으로 특정 패스 요청이 발생했을 때 사용할 콜백 함수를 지정합니다. delete(callback) DELETE 방식으로 특정 패스 요청이 발생했을 때 사용할 콜백 함수를 지정합니다. all(callback) 모든 요청 방식을 처리하며, 특정 패스 요청이 발생했을 때 사용할 콜백 함수를 지정합니다.

웹페이지와 서버 코드 수정 <form method="post" action="/process/login"> login2.html 파일의 코드 <form method="post" action="/process/login"> 서버 코드 var router = express.Router(); router.route('/process/login').post(function(req, res) { console.log('/process/login 처리함.'); var paramId = req.body.id || req.query.id; var paramPassword = req.body.password || req.query.password; res.writeHead('200', {'Content-Type':'text/html;charset=utf8'}); res.write('<h1>Express 서버에서 응답한 결과입니다.</h1>'); res.write('<div><p>Param id : ' + paramId + '</p></div>'); res.write('<div><p>Param password : ' + paramPassword + '</p></div>'); res.write("<br><br><a href='/public/login2.html'>로그인 페이지로 돌아가기</a>"); res.end(); }); app.use('/', router);

요청 패스에 따라 라우팅하는 과정 등록한 요청 패스에 해당하는 함수를 실행 http://localhost:3000/public/login2.html 등록한 요청 패스에 해당하는 함수를 실행

URL 파라미터 사용하기 GET 방식의 파라미터  query 객체, POST 방식의 파라미터  body 객체 URL 파라미터  params 객체 router.route('/process/login/:name').post(function(req, res) { console.log('/process/login/:name 처리함.'); var paramName = req.params.name; var paramId = req.body.id || req.query.id; var paramPassword = req.body.password || req.query.password; res.writeHead('200', {'Content-Type':'text/html;charset=utf8'}); res.write('<h1>Express 서버에서 응답한 결과입니다.</h1>'); res.write('<div><p>Param name : ' + paramName + '</p></div>'); res.write('<div><p>Param id : ' + paramId + '</p></div>'); res.write('<div><p>Param password : ' + paramPassword + '</p></div>'); res.write("<br><br><a href='/public/login2.html'>로그인 페이지로 돌아가기</a>"); res.end(); });

URL 파라미터 방식으로 요청 URL 안에 파라미터가 포함되도록 요청 URL 안에 들어간 파라미터가 매핑되는 형식 <form method="post" action="/process/login/mike"> URL 안에 들어간 파라미터가 매핑되는 형식 /process/login/mike ↓ /process/login/:name

오류 페이지 보여주기 등록되지 않은 요청 패스일 경우 오류 페이지 표시 app.all('*', function(req, res) { res.status(404).send('<h1>ERROR - 페이지를 찾을 수 없습니다.</h1>'); });

express-error-handler 미들웨어로 오류 페이지 보여주기 모듈을 사용하면 미리 만들어진 페이지를 보낼 수 있음 var expressErrorHandler = require('express-error-handler'); var errorHandler = expressErrorHandler({ static: { '404': './public/404.html' } }); app.use( expressErrorHandler.httpError(404) ); app.use( errorHandler );

에러 페이지 생성 public 폴더 안에 404.html 파일 생성하고 모듈 설치 <!DOCTYPE html> <head> <meta charset="UTF-8"> <title>오류 페이지</title> </head> <body> <h3>ERROR - 페이지를 찾을 수 없습니다.</h3> <hr/> <p>/public/404.html 파일의 오류 페이지를 표시한 것입니다.</p> </body> </html> % npm install express-error-handler --save

에러 페이지를 표시하기까지의 과정 등록된 요청 패스를 찾지 못하는 경우

5. 쿠키와 세션 관리하기 난이도 소요시간 20분

res.cookie( ‘쿠키이름‘, ‘쿠키객체') 쿠키 처리하기 쿠키는 클라이언트 웹 브라우저에 저장되는 정보, 세션은 웹 서버에 저장되는 정보 웹서버에서 응답할 때 쿠키를 설정하면 그 정보를 받은 웹브라우저에서 쿠키 저장 응답할 때 응답 객체에 쿠키 설정 : req.cookie() 메소드 호출 웹브라우저에서 웹서버로 요청할 때 쿠키 정보 전송 요청 객체에 들어있는 쿠키 확인 : req.cookies 객체 안의 속성으로 확인 브라우저에 저장 쿠키 설정 res.cookie( ‘쿠키이름‘, ‘쿠키객체') 쿠키 확인 req.cookies.‘쿠키이름‘ 요청 시 쿠키 포함

쿠키 처리하기 var cookieParser = require('cookie-parser'); app.use(cookieParser());

쿠키 처리하기 응답 객체의 cookie() 메소드 호출 router.route('/process/setUserCookie').get(function(req, res) { console.log('/process/setUserCookie 호출됨.'); // 쿠키 설정 res.cookie('user', { id: 'mike', name: '소녀시대', authorized: true }); // redirect로 응답 res.redirect('/process/showCookie');

쿠키 처리하기 router.route('/process/showCookie').get(function(req, res) { 요청 객체의 cookies 속성 사용 router.route('/process/showCookie').get(function(req, res) { console.log('/process/showCookie 호출됨.'); res.send(req.cookies); });

쿠키가 처리되는 방식 웹 브라우저의 쿠키 저장소에 저장됨 요청 객체의 cookies 속성 사용 % npm install cookie-parser --save

세션 처리하기 쿠키는 클라이언트 웹 브라우저에 저장되는 정보, 세션은 웹 서버에 저장되는 정보 웹서버에서 요청 객체에 세션을 설정하면 유지됨  req.session.세션이름 = 세션객체 그 정보를 받은 웹브라우저에서도 connect.sid 쿠키 저장 웹브라우저에서 웹서버로 요청할 때 connect.sid 쿠키 정보 전송 요청에 들어있는 세션 정보 확인  req.session.세션이름 브라우저에서 쿠키로 유지 connect.sid 세션 설정 req.session.세션이름 = 세션객체 세션 확인 req.session.세션이름 요청 시 쿠키 포함 connect.sid

세션이 처리되는 방식 로그인하면 세션이 만들어지고 로그아웃하면 세션이 삭제되도록 만들 수 있음

express-session 모듈 사용 // Session 미들웨어 불러오기 모듈을 불러들이고 미들웨어로 사용 // Session 미들웨어 불러오기 var expressSession = require('express-session'); // 세션 설정 app.use(expressSession({ secret:'my key', resave:true, saveUninitialized:true }));

로그인 시의 세션 처리 요청 객체의 session 속성에 세션 정보 추가 router.route('/process/login').post(function(req, res) { console.log('/process/login 호출됨.'); var paramId = req.body.id || req.query.id; var paramPassword = req.body.password || req.query.password; if (req.session.user) { // 이미 로그인된 상태 console.log('이미 로그인되어 상품 페이지로 이동합니다.'); res.redirect('/public/product.html'); } else { // 세션 저장 req.session.user = { id: paramId, name: '소녀시대', authorized: true };

로그아웃 시의 세션 처리 요청 객체의 session 속성에 세션 정보가 있는지 확인 router.route('/process/logout').get(function(req, res) { console.log('/process/logout 호출됨.'); if (req.session.user) { // 로그인된 상태 console.log('로그아웃합니다.'); req.session.destroy(function(err) { if (err) {throw err;} console.log('세션을 삭제하고 로그아웃되었습니다.'); res.redirect('/public/login2.html'); }); } else { // 로그인 안된 상태 console.log('아직 로그인되어있지 않습니다.'); }

다른 페이지에서 세션 정보 확인 상품 정보 확인 페이지에서 세션 정보 확인 router.route('/process/product').get(function(req, res) { console.log('/process/product 호출됨.'); if (req.session.user) { res.redirect('/public/product.html'); } else { res.redirect('/public/login2.html'); } });

웹페이지 만들기 product.html 페이지 등 생성 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>상품 페이지</title> </head> <body> <h3>상품정보 페이지</h3> <hr/> <p>로그인 후 볼 수 있는 상품정보 페이지입니다.</p> <br><br> <a href='/process/logout'>로그아웃하기</a> </body> </html>

6. 파일 업로드 기능 만들기 난이도 소요시간 20분

multer 미들웨어를 이용한 파일 업로드 // 파일 업로드용 미들웨어 파일 업로드 시 POST 방식으로 요청해야 하며 body-parser 미들웨어 사용 필요 fs, cors 모듈도 사용 // 파일 업로드용 미들웨어 var multer = require('multer'); var fs = require('fs'); //클라이언트에서 ajax로 요청 시 CORS(다중 서버 접속) 지원 var cors = require('cors'); % npm install multer --save % npm install cors --save

multer 미들웨어 설정 업로드 가능한 파일 크기 등을 설정할 수 있음 파일 저장을 위한 폴더 설정 및 파일명 변경 가능 var storage = multer.diskStorage({ destination: function (req, file, callback) { callback(null, 'uploads') }, filename: function (req, file, callback) { callback(null, file.originalname + Date.now()) } }); var upload = multer({ storage: storage, limits: { files: 10, fileSize: 1024 * 1024 * 1024

라우팅 함수에서 업로드된 파일 처리 요청 객체의 files 속성으로 업로드된 파일을 확인할 수 있음 router.route('/process/photo').post(upload.array('photo', 1), function(req, res) { console.log('/process/photo 호출됨.'); try { var files = req.files; console.dir('#===== 업로드된 첫번째 파일 정보 =====#') console.dir(req.files[0]); console.dir('#=====#') // 현재의 파일 정보를 저장할 변수 선언 var originalname = '', filename = '', mimetype = '', size = 0; if (Array.isArray(files)) { // 배열에 들어가 있는 경우 (설정에서 1개의 파일도 배열에 넣게 했음) console.log("배열에 들어있는 파일 갯수 : %d", files.length);

라우팅 함수에서 업로드된 파일 처리 파일 객체에는 originalname, filename, mimetype, size 등의 속성이 들어있음' … for (var index = 0; index < files.length; index++) { originalname = files[index].originalname; filename = files[index].filename; mimetype = files[index].mimetype; size = files[index].size; } } else { // 배열에 들어가 있지 않은 경우 (현재 설정에서는 해당 없음) console.log("파일 갯수 : 1 "); filename = files[index].name; console.log('현재 파일 정보 : ' + originalname + ', ' + filename + ', ' + mimetype + ', ' + size);

클라이언트 웹 페이지 작성 <form> 태그를 사용하고 enctype을 multipart/form-data로 함 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>파일 업로드 테스트</title> </head> <body> <h1>파일 업로드</h1> <br> <form method="post" enctype="multipart/form-data" action="/process/photo"> <table> <tr> <td><label>파일</label></td> <td><input type="file" name="photo" /></td> </tr> </table> <input type="submit" value="업로드" name="submit" /> </form> </body> </html>

실행하여 파일 업로드 확인 <form> 태그를 사용하고 enctype을 multipart/form-data로 함 ▶ http://localhost:3000/public/photo.html

파일 업로드 시 서버 쪽 로그 업로드된 파일 정보 확인 가능

파일 업로드 방식 multipart 포맷으로 전송하는 일반적인 표준 업로드 방식 사용

참고 문헌 [ References] 기본 서적 2017, 정재곤, “Do it! Node.js 프로그래밍 (개정판)”, 이지스퍼블리싱 Node.js Site http://nodejs.org/