본문 바로가기

Node

Node.js - 웹 서버 구축 (Express 미들웨어)

Node.js는 메모리상에서 실행되기 때문에 속도가 빠르다

Node.js 를 이용하여 웹 서버를 만들어 보자

 

 

Middleware 함수

  • 클라이언트에게 요청이 오고 그 요청을 보내기 위해 응답하려는 거쳐가는 중간다리 함수들이다
  • 미들웨어 함수는 req 객체, res 객체, 어플리케이션 요청-응답 사이클 도중 그 다음의 미들웨어 함수에 대한 액세스 권한을 갖는 함수이다
  • next 함수를 이용해서 다음 미들웨어로 현재 요청을 넘길 수 있다

 

app.use 안에 있는 모든 함수들은 모두 미들웨어이며 요청이 올때마다 이 미들웨어를 거치며 클라이언트에게 응답하게 된다.

 

 

IP를 지정 안했으면 http://127.0.0.1:3000/ 또는 http://localhost:3000/ 로 접속

Router를 정의하지 않았어도 서버는 시작 된 상태가 될 수 있다. 
페이지 들어갈 때  Cannot GET / 이 뜨는건 Router를 정의하지 않았기 때문이다

 

var express = require("express");
var http = require("http");

//Express 객체 생성
var app = express();

//브라우저에서 Request 가 왔을때 서버에서 어떤 작업을 할 지 Router 를 통하여 설정하기	
app.use(function(req,res,next) {
	req.user = "suzi"; // req 객체에 user 속성 추가	
	next(); // 다음 미들웨어로 처리순서를 넘김 
});

// 이 코드가 없으면 웹 접속 시 Cannot GET / 이 뜬다
app.use("/",function(req,res,next) {
	res.writeHead("200", {"Content-Type":"text/html;charset=utf-8"});
	res.end("<h1>Express 서버에서 " + req.user + " 응답한 결과입니다</h1>"); 
	// res.write로 길게 안쓰고 res.end에 간결하게 보내줌 			
});

app.set("port",process.env.PORT || 3000);

//Express 서버 시작
http.createServer(app).listen(app.get("port"),function(){
	console.log("익스프레스 서버를 시작했습니다: " + 
			app.get("port"));
	});

 

 

 

 

Middleware 함수를 이용한 기초 예제

JSON 형태의 데이터를 클라이언트한테 바로 보내버리기

app.use(function(req,res,next) {
	res.send({name:"소녀시대",age:30}); // json형태의 데이터를 클라이언트한테 그냥 보내버림	
	next(); // 다음 미들웨어로 처리순서를 넘김 
    });


app.use("/",function(req,res,next) {
	res.writeHead("200", {"Content-Type":"text/html;charset=utf-8"});
	res.end("<h1>Express 서버에서 " + req.user + " 응답한 결과입니다</h1>"); 
	// res.write로 길게 안쓰고 res.end에 간결하게 보내줌 			
});

app.set("port",process.env.PORT || 3000);

//Express 서버 시작
http.createServer(app).listen(app.get("port"),function(){
	console.log("익스프레스 서버를 시작했습니다: " + 
			app.get("port"));
	});

 

다른 url 로 redirect 시키기

app.use(function(req,res,next) {
	res.redirect("http://m.naver.com"); // 이 페이지로 들어오면 바로 네이버로 옮겨지게끔 (url 잘못쳤을때 안내해주기 유용)
});

app.set("port",process.env.PORT || 3000);

//Express 서버 시작
http.createServer(app).listen(app.get("port"),function(){
	console.log("익스프레스 서버를 시작했습니다: " + 
			app.get("port"));
	});

 

 

 

 

접근 금지 페이지 만들기

var express = require("express");
var http = require("http");

var app = express();

app.use(function(req,res,next) {
	res.status(403).send("접근 금지!");
});

app.set("port",process.env.PORT || 3000);

http.createServer(app).listen(app.get("port"),function(){
	});

 

GET방식일 때의 데이터를 받아내는 방법 (라우터X)

var express = require("express");
var http = require("http");

var app = express();

app.use(function(req,res,next){	// 미들웨어
	
	var userAgent = req.header("User-Agent");
	var paramName = req.query.name; // get방식일때만 받아낼 수 있음
	//var paramName = req.param("name"); - get방식, post방식 다 받아낼 수 있음
	
	res.writeHead("200",
			{"Content-Type":"text/html;charset=utf-8"});
	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(); 

	
});

//Express 서버 시작
http.createServer(app).listen(3000,function(){
	});

아직 라우터가 없는 무조건 다 띄워주는 상태이다 
미리 만들어져있는 미들웨어를 쓰면 주소를 구분할 수 있다 /a/.., /b/..

 

http://localhost:3000/?name=suzi 이런 형식의 주소가 node.js로 만들어진 것

 


 

Express 미들웨어 - static, body-parser 

** 외장모듈 설치 - 설치 완료 후 node_modules 하위 폴더에서 확인 가능
ExpressExe>npm install serve-static --save  가상url로 접근을 가능하게 해주는 모듈
ExpressExe>npm install body-parser --save    post방식을 지원하는 모듈

 

 

 

 

 

app.use(serveStatic(path.join(__dirname,"public")));

 

__dirname은 C:\NodeJS\work\ExpressExe 경로를 뜻한다
함수의 인자는 정적 파일들이 담겨있는 폴더를 지정하면 된다 (public 폴더 지정)
여길 이제 루트로 만들겠다는 뜻이므로

public/index.html은   http://localhost:3000/index.html 로 접근한다

실제 서버의 폴더 경로에는 public이 들어 있지만 요청 주소에는 public이 들어 있지 않다는 점을 주목하자

서버의 폴더 경로와 요청 경로가 다르므로 외부인이 서버의 구조를 쉽게 파악할 수 없어 보안유지에 도움이 된다

 

var express = require("express");
var http = require("http");
var path = require("path"); //경로작업

// Express의 미들웨어 불러오기
var bodyParser = require("body-parser"); 
var serveStatic = require("serve-static");

var app = express();
app.set("port",process.env.PORT || 3000);

app.use(bodyParser.urlencoded({extended:false}));
// form 에서 enctype에 나오는 그 urlencoded랑 같은 것
// application/x-www-form-urlencoded => 이거로 쓰겠다? false (기본)
// 객체 안에 객체를 파싱할수 있게끔 하려면 true 써야함

//body-parser를 이용해서 json 데이터를 파싱
app.use(bodyParser.json());

app.use(serveStatic(path.join(__dirname,"public")));


app.use(function(req,res,next){
	
	var paramId = req.body.id || req.query.id;
	// req.body.id : post방식
	// req.query.id : get방식
	// 둘중하나로 받아라
	var paramPwd = req.body.pwd || req.query.pwd;	
	
	res.writeHead("200",
			{"Content-Type":"text/html;charset=utf-8"});
	res.write("<h1>Express 서버</h1>");
	res.write("<div><p>id: " + 
			paramId + "</p></div>");
	res.write("<div><p>pwd: " + paramPwd  + "</p></div>");
	res.end(); 
	
	
});


http.createServer(app).listen(3000,function(){
	});

 

 

Express 객체 - router

router 객체 : 주소 분배 작업을 해준다
이제는 라우터를 통해 주소로 분배하므로 미들웨어 안에서 분배작업을 안해도 된다

결과적으로 router의 갯수는 많아지고 미들웨어의 코딩은 단순해진다.

 

미들웨어를 이용해서 분배작업을 할 때

app.use(function(req,res,next){
..
}

router를 이용해서 분배작업을 할 때

router.post("/process/login",function(req,res){ 
..
}

 

var express = require("express");
var http = require("http");
var path = require("path"); 

var bodyParser = require("body-parser"); 
var serveStatic = require("serve-static"); 

var app = express();
app.set("port",process.env.PORT || 3000);

app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());

// 이 코드는 router 위에 나와야함
app.use("/public",serveStatic(path.join(__dirname,"public")));  

var router = express.Router();

router.post("/process/login",function(req,res){ 
	//post방식으로 왔을 때 '/process/login' 이 주소를 처리해라
	var paramId = req.body.id || req.query.id;
	var paramPwd = req.body.pwd || req.query.pwd;	
	
	res.writeHead("200",
			{"Content-Type":"text/html;charset=utf-8"});
	res.write("<h1>Express 서버</h1>");
	res.write("<div><p>id: " + 
			paramId + "</p></div>");
	res.write("<div><p>pwd: " + paramPwd  + "</p></div>");
	res.write("<br/><br/><a href='/public/login2.html'>돌아가기</a>"); 
	res.end(); 
	
});

/*// public/index.html  이렇게 안해도 되고 바로 /index.html


// 라우터 객체를 app에 등록해주기. => 그래야 서버가 인식을 함
app.use("/",router);

http.createServer(app).listen(3000,function(){
	});

 

 

URL 요청파라미터로 값 받기

= post 방식 요청 Path 의 맨 뒤 경로를 값으로 쓰겠다는 것

submit 을 할때 경로 끝에 /hi 를 붙여 이것이 경로가 아닌 파라미터로 넘어가게 한다

 

login3.html

<form action="/process/login/hi" method="post">

 

 

app5.js

router.post("/process/login/:name",function(req,res){ 

var paramName = req.params.name; // 이 name은 위의 name과 명을 맞춰줘야함
...}

 

 

요청URL에 포함된 파라미터(token)를 사용해서 데이터를 넘기는 방법 

& 사용자 정의 에러 페이지 만들기

get방식만 이 방법이 가능

/process/users/의 토큰을 사용해서 넘겨본다

var express = require("express");
var http = require("http");
var path = require("path");

// Express의 미들웨어 불러오기
var bodyParser = require("body-parser");
var serveStatic = require("serve-static"); 

// 에러 핸들러 모듈
var expressErrorHandler = require("express-error-handler");
var errorHandler = require("errorhandler");

var app = express();
app.set("port",process.env.PORT || 3000);

app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());

app.use("/public",serveStatic(path.join(__dirname,"public")));  
var router = express.Router();

//get방식으로 주소를 보냈을 때 그 주소 안에 있는 param값을 받는다 
//입력창 필요 x
router.route("/process/users/:id").get(function(req,res){ 
	
	var paramId = req.params.id; // get방식으로 넘어온건 params로 받는다
	
	console.log("/process.users의 토큰을 사용: " + paramId);	
	
	res.writeHead("200",
			{"Content-Type":"text/html;charset=utf-8"});
	res.write("<h1>Express 서버7</h1>");
	res.write("<div><p>인원수: " + paramId +"</div>");
	 
	res.end(); 
	
});

// 라우터 객체를 app에 등록
app.use("/",router);

// 404 에러 처리
var errorHandler = expressErrorHandler({
	static:{
		"404":"./public/404.html"		
	}
});

//미들웨어등록
app.use(expressErrorHandler.httpError(404)); //404에러가 났을 때 실행해라
app.use(errorHandler);

//Express 서버 시작
http.createServer(app).listen(3000,function(){
	});

 

 

잘못된 주소 입력 시

 

 

cookie-parser 모듈 

요청된 쿠키를 쉽게 추출할 수 있도록 해주는 미들웨어. request 객체에 cookies 속성이 부여된다.

 

*Cookie는 사용자의 정보가 웹 서버를 통해 사용자의 컴퓨터에 직접 저장되는 정보의 단위

예를 들어 사이트에 접속을 했는데 “아이디와 비밀번호를 저장하시겠습니까?” 라는 창이 뜨면 사용자의 아이디와 비밀번호를 쿠키로 저정한다는 뜻이다

 

npm install cookie-parser --save

// <사용자정의 에러페이지>
var express = require("express");
var http = require("http");
var path = require("path");

// Express의 미들웨어 불러오기
var bodyParser = require("body-parser");
var serveStatic = require("serve-static"); 

// 에러 핸들러 모듈
var expressErrorHandler = require("express-error-handler");
var errorHandler = require("errorhandler");

//CooKie 모듈
var cookieParser = require("cookie-parser"); 

var app = express(); // 미들웨어 등록은 이 아래에 써줘야함. app 먼저 생성하고 써야하는거니깐
app.set("port",process.env.PORT || 3000);

//미들웨어 등록
app.use(cookieParser());
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());

app.use("/public",serveStatic(path.join(__dirname,"public")));  
var router = express.Router();


router.route("/process/showCookie").get(function(req,res){ 
	
	console.log("/process/showCookie 호출됨");
	
	res.send(req.cookies); 
	
});


router.route("/process/setUserCookie").get(function(req,res){ 
	
	console.log("/process/setUserCookie 호출됨");
	
	// 쿠키 설정 
	res.cookie("user",{
		id:"suzi",
		name:"배수지",
		authorize:true // 
	});
	
	//redirect로 응답
	res.redirect("/process/showCookie");
	
});



// 라우터 객체를 app에 등록
app.use("/",router);


// 404 에러 처리
var errorHandler = expressErrorHandler({
	static:{
		"404":"./public/404.html"		
	}
});

//미들웨어 등록
app.use(expressErrorHandler.httpError(404)); //404에러가 났을 때 실행해라
app.use(errorHandler);


//Express 서버 시작
http.createServer(app).listen(3000,function(){
	console.log("익스프레스 서버가 3000번 포트에서 시작했습니다: ");
	});

 

 

express-session 모듈 

npm install express-session --save

세션사용, 대표적으로 login 작업에 이용한다

 

헷갈리지 말 것

가상주소 /pub/product
실제주소 ./public/404.html 
가상주소에는 앞에 ./ 경로로 넣어줄 필요 없음

 

express-session은 인자로 세션에 대한 설정을 받는다

[express-session 옵션]

 resave

 요청이 왔을 때 세션에 수정사항이 생기지 않더라도 세션을 다시 저장할지에 대한 설정 (true-secret 키값 그대로 유지)

 saveuninitialized

 세션에 저장할 내역이 없더라도 세션을 저장할지 대한 설정 (보통 방문자를 추적할 때 사용된다.)

 secret

 필수항목으로 cookie-parser의 비밀 키와 같은 역할을 한다 (세션을 임의로 변조하는 것을 방지)

 cookie

 세션 쿠키에 대한 설정

* 안전하게 쿠키를 전송하려면 쿠키에 서명을 추가해야 하고, 쿠키를 서명하는데 secret의 값이 필요하다.

이때 cookie-parser의 secret과 같게 설정해야 한다 

 

login4.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>login4</title>
</head>
<body>

<h1>login4</h1><br/>
<form action="/process/login" method="post">

<table>
<tr>
	<td>아이디</td>
	<td><input type="text" name="id"/></td>
</tr>

<tr>
	<td>비밀번호</td>
	<td><input type="password" name="pwd"/></td>
</tr>
</table>

<input type="submit" value="전송"/>

</form>

<a href="/process/product">상품정보</a>
<a href="/process/logout">로그아웃</a>

</body>
</html>

 

app9.js

express-session은 cookie-parser 미들웨어 뒤에 놓는 것이 안전

//npm install express-session --save
//세션사용 (대표적으로 login작업)

var express = require("express");
var http = require("http");
var path = require("path");

// Express의 미들웨어 불러오기
var bodyParser = require("body-parser");
var serveStatic = require("serve-static"); 

// 에러 핸들러 모듈
var expressErrorHandler = require("express-error-handler");
var errorHandler = require("errorhandler");

//CooKie 모듈
var cookieParser = require("cookie-parser"); 

//Session 모듈
var expressSession = require("express-session");

var app = express(); // 미들웨어 등록은 이 아래에 써줘야함. app 먼저 생성하고 써야하는거니깐
app.set("port",process.env.PORT || 3000);


//미들웨어 등록
app.use(cookieParser());
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());

app.use(expressSession({
	secret:"myKey", // 사용자 정의 세션 이름
	resave:true,
	saveUninitialized:true	
}));

app.use("/pub",serveStatic(path.join(__dirname,"public")));  
// public이라는 실제 폴더를 => /pub 이라고 가상주소로 쓰겠다

var router = express.Router();

// app:미들웨어 router:라우터
// 이 두개를 합쳐서 app.post로 써또 됨

//즉, app.post -> router.post로 써도 다 작동됨 
app.post("/process/login", function(req,res){ 
	var paramId = req.body.id || req.query.id;
	var paramPwd = req.body.pwd || req.query.pwd;
	
	if (req.session.user) {		
		//로그인 된 상태
		res.redirect("/pub/product.html");
		
	} else {
		
		// 세션 저장하는 작업
		if(paramId=="suzi" && paramPwd=="123"){
			
			req.session.user = {
					id:paramId,
					name:"배수지",
					authorized:true
			};
			
			res.writeHead("200",
					{"Content-Type":"text/html;charset=utf-8"});
			res.write("<h1>Express 서버9</h1>");
			res.write("<h3>로그인성공</h3>");
			res.write("<div><p>id: " + 
					paramId + "</p></div>");
			res.write("<div><p>pwd: " + paramPwd  + "</p></div>");
			
			
			res.write("<div><p>name : "
					+ req.session.user.name + " </p></div>"); // 세션을 위에서 넣었기 때문에 아래서 읽을 수 있음
			
			
			res.write("<br/><br/><a href='/process/product'>상품보러가기</a>"); // public이란 폴더가 
			
			res.end(); 
			
		}
		
	}	
	
});


app.get("/process/product", function(req,res){ 
	
	console.log("/process/product 호출됨");
	
	// 로그인상태일 때만 이 페이지가 보여져야함
	if(req.session.user) {		
		res.redirect("/pub/product.html"); 
	} else {
		res.redirect("/pub/login4.html");		
	}	
	
});


app.get("/process/logout",function(req,res){ 
	
	if(req.session.user) {
		//세션 삭제
		req.session.destroy(function(err){
			
			if(err) {
				throw err;
			}
			
			else {
				res.redirect("/pub/login4.html");	
			}
			
		});
		
		
	} else {
		res.redirect("/pub/login4.html");
	}	
});



// 라우터 객체를 app에 등록
app.use("/",router);


// 404 에러 처리
var errorHandler = expressErrorHandler({
	static:{
		"404":"./public/404.html"		
	}
});


//미들웨어 등록
app.use(expressErrorHandler.httpError(404)); //404에러가 났을 때 실행해라
app.use(errorHandler);


//Express 서버 시작
http.createServer(app).listen(3000,function(){
	});

 

 

 

출처: https://backback.tistory.com/339 [Back Ground]

'Node' 카테고리의 다른 글

Node.js + Oracle  (0) 2019.11.06
Node.js + MongoDB  (0) 2019.11.04
Node.js - winston 모듈 (미완)  (0) 2019.11.01
Node.js - 이벤트처리, 파일다루기, 버퍼객체  (0) 2019.11.01
Node.js - express 모듈을 이용한 서버 구축  (0) 2019.10.31