본문 바로가기
nodejs

[node.js] 웹서버 만들기

by jackypark 2022. 9. 22.

이번 내용은 node.js를 사용해서 다양한 방법으로 서버를 구축해보는 것에 대해 포스팅하겠습니다.

웹서버에서 사용자의 정보를 관리하는 기능을 하나씩 만들어 보면서 웹 서버의 기본 기능을 차례대로 설명하겠습니다.

 

1.HTTP 모듈로 웹 서버 시작

  • 노드에 기본으로 들어있는 http 모듈을 사용하여 웹 서버 객체 만듭니다. 보통은 나중에 설명드릴 express를 가장 많이 사용합니다.

간단 코드로 웹서버 한번 실행시키기

var http = require('http');

var server = http.createServer();//웹서버 객체가 리턴

var host = 'localhost';// 보통 ip를넣음

var port=3000;// 3000번 포트 사용

server.listen(port,host,'50000',function(){ 
    console.log('웹서버가 실행되었습니다->'+host+':'+port);
});//서버를 실행하여 대기 시킴.... 숫자가 의미하는건 서버에 접속할수있는 최대 인원을 가르킴
//웹서버가 명시적으로 중지를 안시키면 중지를 하지않음


server.on('connection',function(socket){
    console.log('클라이언트가 접속했습니다. ');
}); // server객체가 이벤트객체를 상속받고있기 떄문에 사용 쌉가능

server.on('request',function(req,res){ //req 요청객체 res 응답객체
    console.log('클라이언트 요청이 들어왔습니다. ');
    //console.dir(req);

    res.writeHead(200,{"Content-Type":"text/html;charset=utf-8"}); //헤더정보를 클라이언트에 전송
    res.write('<h1>웹서버로부터 받은 응답</h1>');
    res.end();
});

실행화면

이미지 파일 업로드는 아래 코드를 활용해 출력이 가능합니다.

server.on('request',function(req,res){ //req 요청객체 res 응답객체
    console.log('클라이언트 요청이 들어왔습니다. ');
    //console.dir(req);

    var filename='back.jfif';
    fs.readFile(filename,function(err,data){ //이미지 업로드 하기
        res.writeHead(200,{"Content-Type":"image/png"}); //헤더정보를 클라이언트에 전송
        res.write(data);
        res.end();
    });
});

이미지 파일 이외에도 텍스트 파일이나 음악파일 등을 보낼 수 있음

그리고 다른 웹사이트의 데이터도 가져올 수 있음

 

2.Express 모듈을 사용하여 웹서버를 구축

  • 미드웨어로 클라이언트에 응답을 보내야 한다
  • 미들웨어는 중간에 요청을 처리하고 라우터는 요청 패스에 따라 분기하여 처리

다음으로 넘어가는 건 next()가 꼭 필요 설정은 use()로 설정

미들웨어 함수는 요청 오브젝트(req), 응답 오브젝트 (res), 그리고 애플리케이션의 요청-응답 주기 중 그다음의 미들웨어 함수 대한 액세스 권한을 갖는 함수입니다. 그다음의 미들웨어 함수는 일반적으로 next라는 이름의 변수로 표시됨.

미들웨어 함수는 다음과 같은 태스크를 수행할 수 있습니다.

  • 모든 코드를 실행.
  • 요청 및 응답 오브젝트에 대한 변경을 실행.
  • 요청-응답 주기를 종료.
  • 스택 내의 그 다음 미들웨어를 호출.

간단하게 미들웨어를 등록해서 클라이언트에 응답을 보내보겠습니다

우선 터미널에 express 모듈을 설치해야 합니다. npm install express

// Express 기본 모듈 불러오기
var express = require('express');
var http = require('http');

var app = express();// 익스프레스 서버 객체 생성

app.set('port',process.env.PORT || 3000);//포트라고 하는 환경변수를 사용하거나 3000을 사용해라

app.use(function(req,res,next){//http모듈과 동일하게 응답,요청객체를 파라미터로 받음
    console.log('첫번째 미들웨어 호출됨.');

    res.writeHead(200,{"Content-Type":"text/html;charset=utf8"});
    res.end('<h1>서버에서 응답한 결과입니다.</h1>'); //내용전송하면서 끝

});// 미들웨어 등록

var server = http.createServer(app).listen(app.get('port'),function(){
    console.log('익스프레스로 웹서버 실행함: '+ app.get('port'));
});// 익스프레스를 이용해서 웹서버 만들기

보시다 싶이 개발자 도구에서 content type을 확인해보면 내가 코드 한 그대로 설정 되어있다.

두 개의 미들웨어를 사용할 때의 구성할 때는 아래와 같습니다

// Express 기본 모듈 불러오기
var express = require('express');
var http = require('http');

var app = express();// 익스프레스 서버 객체 생성

app.set('port',process.env.PORT || 3000);//포트라고 하는 환경변수를 사용하거나 3000을 사용해라

app.use(function(req,res,next){//http모듈과 동일하게 응답,요청객체를 파라미터로 받음
    console.log('첫번째 미들웨어 호출됨.');

    req.user = 'jacky';//유저 속성 추가

    next();// next를 만나면 현재 미들웨어를 떠나게됨

});// 미들웨어 등록

app.use(function(req,res,next){
  
  바로 아래 코드 확인바람

});//두번째 미들웨어 등록

var server = http.createServer(app).listen(app.get('port'),function(){
    console.log('익스프레스로 웹서버 실행함: '+ app.get('port'));
});// 익스프레스를 이용해서 웹서버 만들기

첫번째 미들웨어

app.use(function(req,res,next){
    console.log('두번째 미들웨어 호출됨. ')

    //res.send('<h1>서버에서 응답한 결과입니다:'+ req.user+' </h1>'); //내용전송하면서 끝

    var person={name:'소녀시대',age:20};
    //res.send(person);  //js객체 넘기면? json포맷으로 출력됨//동일결과

    var personStr=JSON.stringify(person);//명시적으로 string형태로 변환해서 보냄
    //res.send(personStr);//아래와 동일결과

    res.writeHead(200,{"Content-Type":"application/json;charset=utf8"});
    res.write(personStr);
    res.end();

});//두번째 미들웨어 등록

2번째 미들웨어 내용

3. 미들웨어 사용하기

static 미들웨어

  • 특정 폴더의 파일들을 특정 패스로 접근할 수 있도록 열어주는 역할을 함

그리고 여기도 당연히 Get방식과 Post방식이 존재한다

GET 방식

// Express 기본 모듈 불러오기
var express = require('express');
var http = require('http');

var app = express();// 익스프레스 서버 객체 생성

app.set('port',process.env.PORT || 3000);//포트라고 하는 환경변수를 사용하거나 3000을 사용해라

app.use(function(req,res,next){//http모듈과 동일하게 응답,요청객체를 파라미터로 받음
    console.log('첫번째 미들웨어 호출됨.');

    //res.redirect('http://google.co.kr'); 구글로 이동함

    var UserAgent = req.header('User-Agent');//header에다가 useragent를 뽑아보겠다라는 말
    var paramName = req.query.name; //get방식으로 전송한 요청 파라미터를 확인합니다.

    res.send('<h3>서버에서 응답. User-Agent-> : '+ UserAgent+'</h3>'+
    '<h3>Param Name-> : '+ paramName+'</h3>');
    

});// 미들웨어 등록


var server = http.createServer(app).listen(app.get('port'),function(){
    console.log('익스프레스로 웹서버 실행함: '+ app.get('port'));
});// 익스프레스를 이용해서 웹서버 만들기

get방식으로 아주잘 값이 넘어온것을 url을 확인하면 알 수 있다.

이번에는 Post 방식이다

post방식은 body-parser라는 모듈을 사용하면 된다 npm install body-parser

// Express 기본 모듈 불러오기
var express = require('express');
var http = require('http');
var path = require('path');

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


var app = express();// 익스프레스 서버 객체 생성

app.set('port',process.env.PORT || 3000);//포트라고 하는 환경변수를 사용하거나 3000을 사용해라

//post 방식으로 넘길 경우
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());

app.use(static(path.join(__dirname,'public')));//웹서버에서 퍼블릭 폴더를 열어놓고 있다는 뜻?

app.use(function(req,res,next){//http모듈과 동일하게 응답,요청객체를 파라미터로 받음
    console.log('첫번째 미들웨어 호출됨.');


    var UserAgent = req.header('User-Agent');//header에다가 useragent를 뽑아보겠다라는 말
    var paramName = req.body.id || req.query.id; //post방식 로 쓰이면 body get방식이면 query

    res.send('<h3>서버에서 응답. User-Agent-> : '+ UserAgent+'</h3>'+
    '<h3>Param Name-> : '+ paramName+'</h3>');
    

});// 미들웨어 등록


var server = http.createServer(app).listen(app.get('port'),function(){
    console.log('익스프레스로 웹서버 실행함: '+ app.get('port'));
});// 익스프레스를 이용해서 웹서버 만들기

Post방식으로 제대로 값이 넘어갔는지 확인하기 위해 간단 로그인 화면을 구현하여 확인하였다.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>로그인</title>
    </head>
    <body>
        <h1>로그인</h1><br>
        <form method="post"> 
            <table>
                <tr>
                    <td><label>아이디</label></td>
                    <td><input type="text" name="id"></td>
                </tr> 
                <tr>
                    <td><label>비밀번호</label></td>
                    <td><input type="password" name="password"></td>
                </tr>
            </table>
            <input type="submit" value="전송" name="">
        </form>

    </body>

</html>

로그인화면

 

post방식으로 구동해서 url에는 안보이지만 값을 잘 받아온것을 확인할 수 있다.

4.Router를 사용해 요청 라우팅 하기

  • Express4 에서는 Router 미들웨어가 포함되어있음
  • Router객체를 참조한 후 route() 메서드를 이용해 라우팅
// Express 기본 모듈 불러오기
var express = require('express');
var http = require('http');
var path = require('path');

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

var app = express();// 익스프레스 서버 객체 생성

app.set('port',process.env.PORT || 3000);//포트라고 하는 환경변수를 사용하거나 3000을 사용해라

//post 방식으로 넘길 경우
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());

var router = express.Router();

router.route('/process/login/:name').post(function(req,res){ //route안에 요청패스 이름 .. 음 방학 프로젝트때 mvc패턴할떄 post방식 요청패스 받는거랑 동일한듯?
    console.log('login 라우팅 함수에서 받음.');
    var paramId = req.body.id || req.query.id; //post방식 로 쓰이면 body get방식이면 query
    var paramPassword = req.body.password || req.query.password; //post방식 로 쓰이면 body get방식이면 query

    var paramName=req.params.name;//g토큰? 을 가져옴

    res.writeHead(200,{"Content-Type":"text/html;charset=utf8"});
    res.write("<h1>서버에서 로그인 응답</h1>"); // 보통 뷰에 저장하고 하는데 지금은 기초라서 살작 번거럽게 하는거임
    res.write("<div><p>"+paramName+"</p></div>");
    res.write("<div><p>"+paramId+"</p></div>");
    res.write("<div><p>"+paramPassword+"</p></div>");
    res.end();

});// 여기 요청패스 들어온것만 허용

app.use('/',router);

app.all('*',function(req,res){ // 에러 페이지 뛰우기
    res.status(404).send('<h1>요청하신 페이지가 존재 하지 않습니다</h1>');
});

app.use(static(path.join(__dirname,'public')));//웹서버에서 퍼블릭 폴더를 열어놓고 있다는 뜻?

var server = http.createServer(app).listen(app.get('port'),function(){
    console.log('익스프레스로 웹서버 실행함: '+ app.get('port'));
});// 익스프레스를 이용해서 웹서버 만들기

url 요청 파라미터 사용해서 매핑하기

  • Get 방식의 파라미터 → query 객체, Post 방식의 파라미터 → body 객체
  • URL 파라미터 → parmas 객체
 <form method="post" action="process/login/jacky">

아까 로그인 화면에서 action 부분만 수정해주면 제대로 됐는지 확인할 수 있다.

5. 미들웨어로 오류 페이지 보내기

서버 실행 후 웹 브라우 제어서 아무 주소 입력 시 예외처리 페이지를 만든 거임

npm install express-error-handler —save

//오류 핸들러 모듈 사용
var expressErrorHandler=require('express-error-handler');

//모든 router 처리 끝난 후 404오류 페이지 처리
var errorHandler=expressErrorhandler({
	static:{
		'404':'./public/404.html' //404.html로 이동해라
	}
});

app.use(expressErrorHandler.httpError(404) );
app.use( errorHandler);

6. 쿠키와 세션 관리

보통 나중에 로그인을 관리할 때는 passport 모듈을 사용한다고 한다.. 다음에 공부할 때 passport 모듈에 대해 알아봐야겠다.

우선 지금은 노드에서 쿠키 저장 방식에 대해 공부하겠다. 우선 cookie-parser라는 모듈을 설치해야 한다.

npm install cookie-parser --save

 

// Express 기본 모듈 불러오기
var express = require('express');
var http = require('http');
var path = require('path');

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

var app = express();// 익스프레스 서버 객체 생성

app.set('port',process.env.PORT || 3000);//포트라고 하는 환경변수를 사용하거나 3000을 사용해라

//post 방식으로 넘길 경우
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());

app.use(cookieParser());


var router = express.Router();

router.route('/process/setUserCookie').get(function(req,res){
    console.log('/process/setUserCok 호출됨');

    //쿠키설정
    res.cookie('user',{
        id:'mike',
        name:'소녀시대',
        authorized:true //인증돘나
    });
    //redirect로 응답
    res.redirect('/process/showCookie');//여기로 이동
});

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

    res.send(req.cookies);//cookies안에 user가 들어가있음
});

app.use(static(path.join(__dirname,'public')));//웹서버에서 퍼블릭 폴더를 열어놓고 있다는 뜻?


var server = http.createServer(app).listen(app.get('port'),function(){
    console.log('익스프레스로 웹서버 실행함: '+ app.get('port'));
});// 익스프레스를 이용해서 웹서버 만들기

value가 암호화 되있지만 쿠키에 정보가 들어 간것을 확인 할 수 있습니다.

그리고 로그인 시 가장 중요한 Session 구동방식이다.

 

이상으로 웹서버 구축 방법과 쿠키와 세션 관리에 대해 포스팅을 마치겠다.

 

느낀 점..:

생각보다 이해가 많이 안 됐다. 하지만 nodejs에는 다양한 모듈이 있고 그걸 어떻게 활용하느냐에 따라 코딩이 편리 해 질 수 있다는 것을 느꼈다.  다음 포스팅에는 이것들을 종합해서 만든 crud 게시판에 대해 포스팅하겠다.

 

참고서적:doit node.js

댓글