Basic Node.js

Handling HTTP Requests with Node.js

HTTP 전달방식에서는 GET방식, POST 방식이 있는데, 앞서 url을 통해서 데이터를 전달하는 것이 GET방식이다.

GET

요청: localhost:3000/?id=3

위와 같이 url을 입력하게 되면 / 페이지에 접속하는데, id를 3을 전달하겠다라는 의미이다.

다음과 같이 query string을 이용해서 데이터를 전달할 수 있다. 하지만, 정보를 받아오기 위해 query string을 이용하는 것은 좋은 방법이지만, 정보를 수정해야하는 작업에 대해서 위와 같이 query string을 전달하게 되면 url을 통한 무분별한 데이터의 수정이 발생 할 수 있기 때문에, 데이터의 수정을 요하는 작업에 대해서는 GET방식이 아닌 POST 방식을 이용해야한다.

앞서 GET 방식에서는 아래와 같이 url 몬듈의 parse 기능을 이용해서 querystring을 읽어드릴 수 있었다.

const url = require('url');
const app = http.createServer(function(request,response){
    const _url = request.url;
    const queryData=url.parse(_url,true).query;
    const id= query.id;

POST

요청: localhost:3000/

post 요청하는 url에는 직접적으로 요청하는 데이터가 드러나지 않고, 따로 HTTP Body에 넣어서 보내기 때문에 무분별한 데이터의 수정을 막을 수 있다.

POST 방식의 데이터를 전송하기 위해 가장 많이 활용하는 방법이 HTML의 Form 태그를 이용하는 것이다.

<form action="/" method="POST">
    <input name="id" placeholder="title">
    <input name="submit">
</form>

다음과 같이 form 태그를 생성하고, post 방식으로 전송할 수 있다.

그러면 POST 방식으로 전달받은 데이터는 어떻게 읽어드릴까?

const qs=require("querystring");
let body="";

request.on("data",function(data){
    body+=data;
})

request.on("end",function(){
    const post=qs.parse(body);
    console.log(post)
    const id=post.id
       
})

body 객체를 읽어서 안에 있는 parameter들을 알아낸다.

Module

자바스크립트는 객체 단위로 변수들을 관리 할 수 있다. 또한 여러 객체들이 생겼을 경우 공통된 성질을 가지고 있는 객체 끼리 서로 묶어서 하나의 모듈로 관리할 수 있다.

이렇게 하면 나중에 추가적인 코드 구현 없이 모듈을 import해서 미리 구현해놓은 객체들을 이용할 수 있다.

const url = require('url');
const qs = require('querystring');

앞서 require을 통해 사전에 만들어진 모듈들을 import 해서 해당 모듈내에 있는 객체들을 이용했었다.

모듈을 생성하고, 이를 다른 파일에서 이용하는 방법은 아래와 같다

model.js

var M={
    v:'v',
    f:function(){
        console.log(this.v);
    }
}

//모듈로 빼고자 하는 객체
module.exports=M;

model_use.js

const M=require("./model.js")

console.log(M);
M.f();

위와 같이 model_use.js 와 model.js는 다른 파일인데, model_use.js에서 model.js 내에 있는 객체를 이용하고 있다.

Security

만약 최상위 경로에 password.js 라는 폴더가 있고

password.js

const config={
    id:"user123",
    password:"123123"
}
module.exports=config

처럼 되어 있는데, url을 통해 localhost:3000/?id=password.js 라고 요청을 보내게 되면, 아래와 같이 아이디/비밀번호 정보가 그대로 화면에 출력될 수도 있다. security_breach

이런 것을 방지하기 위해 query string에 대한 분석을 철저히 할 필요가 있다.

{
  root: '',
  dir: '..',
  base: 'password.js',
  ext: '.js',
  name: 'password'
}

입력받은 query string에 대해 path 모듈로 분석을 실시해보면 위와 같이 분석되며, 이 객체를 토대로 필요한 정보만(base)을 추출하여 올바른 처리를 할 수 있도록 해준다.

const url = require('url');
const path=require('path');

const queryData=url.parse(_url,true).query;
const title=queryData.id;
const fileteredId=path.parse(title).base;

위와 같이 설정하면 다음과 같은 입력에도 불필요한 정보의 유출을 막을 수 있다.

secutiry_secured

NPM

npm을 이용해서 필요한 모듈들을 설치하고 관리할 수 있다.

우선, 프로젝트 폴더에서 npm 기능을 사용하기 위한 설정을 진행한다.

Initiation

npm init

그러면, package.json 파일이 생기는데, 이는 npm 관련 설정파일이다.

이제, module을 설치해보자

Install module Example(sanitize-html)

npm install -S sanit-html

여기 -S 옵션을 주게 되면 해당 프로젝트에서만 이 모듈을 설치하게 된다.

여기서 설치하는 sanit-html 모듈은 XSS 공격(공격자가 악의적으로 스크립트를 심어놓고 이를 그대로 클라이언트에서 실행되게끔 하는 것)을 방지하기 위해 입력에 대한 검증(HTML 태그 제거)을 한다.

가령 사용자로 하여금

<script>
    location.href="//"
</script>

와 같은 스크립트를 입력하게 되서, 이를 그대로 html에 추가하게 되면 html에서는 이를 javascript 로 인식해서 해당 코드를 실행하게 된다. 그러면 이상한곳으로 redirect되는 문제가 발생한다.

이것을 sanitize-html을 이용하게 되면 html 태그에 대한 부분들을 필터링 할 수 있다.

description=`
<script>
    location.href="//"
</script>`;
const sanitizeHtml=require('sanitize-html');
const sanitizedDescription=sanitizeHtml(description);

//sanitizedDescription을 출력해보면 html태그가 제거된것을 확인 할 수 있다.

API

Application Programming Interface

필요한 모듈, 라이브러리에 기능 상세 설명을 자세하게 기록되어 있으며, 개발자는 자신이 필요한 기능들을 이러한 API를 통해 해당 기능들을 적절하게 이용할 수 있다.

가령 http 모듈의 createServer에 관한 API을 살펴보면

아래와 같다 create_server_api

References

link: node.js

link: node.js doc

댓글남기기