본문 바로가기
JavaScript/Node.js

Node) 노드 기능 알아보기 - 노드 내장 모듈 사용하기

by 박채니 2022. 12. 27.
안녕하세요, 코린이의 코딩 학습기 채니 입니다.
[Node.js 교과서]의 책을 참고하여 포스팅한 개인 공부 내용입니다.

 

노드 기능 알아보기

 

노드 내장 모듈 사용하기

 

노드는 운영체제 정보에 접근, 클라이언트가 요청한 주소에 대한 정보 등을 가져올 수 있으며, 이러한 기능을 하는 모듈을 제공합니다.

 

os

 

  • 노드는 os 모듈에 정보가 담겨 있어 정보를 가져올 수 있음
    (웹 브라우저에 사용되는 js는 운영체제의 정보를 가져올 수 없음)
  • require('os') 또는 require('node:os')로 모듈을 불러옴
    (os라는 파일이 존재하진 않지만, 노드가 알아서 내장 모듈인 것을 파악해 불러옴)

os.js

const os = require("os");

console.log("----- 운영 체제 정보 -----");
console.log("os.arch() : ", os.arch());
console.log("os.platform() : ", os.platform());
console.log("os.type() : ", os.type());
console.log("os.uptime() : ", os.uptime());
console.log("os.hostname() : ", os.hostname());
console.log("os.release() : ", os.release());

console.log("----- 경로 -----");
console.log("os.homedir() : ", os.homedir());
console.log("os.tmpdir() : ", os.tmpdir());

console.log("----- cpu 정보 -----");
console.log("os.cpus() : ", os.cpus());
console.log("os.cpus().length : ", os.cpus().length);

console.log("----- 메모리 정보 -----");
console.log("os.freemem() : ", os.freemem());
console.log("os.totalmem() : ", os.totalmem());

@콘솔출력값
$ node part3/os    

----- 운영 체제 정보 -----
os.arch() :  arm64
os.platform() :  darwin
os.type() :  Darwin
os.uptime() :  20217
os.hostname() :  bagchaeeun-ui-Macmini.local
os.release() :  22.2.0
----- 경로 -----
os.homedir() :  /Users/parkchaeeun
os.tmpdir() :  /var/folders/mf/76z8f5jd7sz8bxxj8ld1bxvm0000gn/T
----- cpu 정보 -----
os.cpus() :  [
  {
    model: 'Apple M1',
    speed: 24,
    times: { user: 1084000, nice: 0, sys: 710790, idle: 13938110, irq: 0 }
  },
  {
    model: 'Apple M1',
    speed: 24,
    times: { user: 996140, nice: 0, sys: 651750, idle: 14092940, irq: 0 }
  },
  {
    model: 'Apple M1',
    speed: 24,
    times: { user: 808850, nice: 0, sys: 525840, idle: 14420260, irq: 0 }
  },
  {
    model: 'Apple M1',
    speed: 24,
    times: { user: 693990, nice: 0, sys: 440660, idle: 14631330, irq: 0 }
  },
  {
    model: 'Apple M1',
    speed: 24,
    times: { user: 755440, nice: 0, sys: 170220, idle: 14859440, irq: 0 }
  },
  {
    model: 'Apple M1',
    speed: 24,
    times: { user: 554510, nice: 0, sys: 130330, idle: 15104160, irq: 0 }
  },
  {
    model: 'Apple M1',
    speed: 24,
    times: { user: 355150, nice: 0, sys: 69070, idle: 15369850, irq: 0 }
  },
  {
    model: 'Apple M1',
    speed: 24,
    times: { user: 220740, nice: 0, sys: 39730, idle: 15537870, irq: 0 }
  }
]
os.cpus().length :  8
----- 메모리 정보 -----
os.freemem() :  869531648
os.totalmem() :  17179869184

 

  • os.arch()
  • os.platform()
  • os.type()
    : 운영체제의 종류를 보여줌
  • os.uptime()
    : 운영체제 부팅 이후 흐른 시간(초)를 보여줌 (process.uptime()은 노드의 실행 시간)
  • os.hostname()
    : 컴퓨터의 이름을 보여줌
  • os.release()
    : 운영체제의 버전을 보여줌
  • os.homedir()
    : 홈 디렉터리 경로를 보여줌
  • os.tmpdir()
    : 임시 파일 저장 경로를 보여줌
  • os.cpus()
    : 컴퓨터의 코어 정보를 보여줌
  • os.freemem()
    : 사용 가능한 메모리(RAM)를 보여줌
  • os.totalmem()
    : 전체 메모리 용량을 보여줌
  • os.constants
    : 각종 에로와 신호에 대한 정보를 가지고 있음

 

path

 

  • 폴더와 파일의 경로를 쉽게 조작하도록 도와주는 모듈
  • 운영체제별로 경로 구분자가 다르기 때문에 path 모듈이 필요

path.js

const path = require("path");

const string = __filename;

console.log("path.sep : ", path.sep);
console.log("path.delimiter : ", path.delimiter);
console.log("---------------------------");
console.log("path.dirname() : ", path.dirname(string));
console.log("path.extname() : ", path.extname(string));
console.log("path.basename() : ", path.basename(string));
console.log(
  "path.basename - extname : ",
  path.basename(string, path.extname(string))
);
console.log("---------------------------");
console.log("path.parse() : ", path.parse(string));
console.log(
  "path.format() : ",
  path.format({
    dir: "C:\\users\\zerocho",
    name: "path",
    ext: "js",
  })
);
console.log(
  "path.normalize() : ",
  path.normalize("C://users\\\\zerocho\\path.js")
);
console.log("---------------------------");
console.log("path.isAbsolute(C:\\) : ", path.isAbsolute("C:\\"));
console.log("path.isAbsolute(./home) : ", path.isAbsolute("./home"));
console.log("---------------------------");
console.log(
  "path.relative() : ",
  path.relative("C:\\users\\zerocho\\path.js", "C:\\")
);
console.log(
  "path.join() : ",
  path.join(__dirname, "..", "..", "/users", ".", "/zerocho")
);
console.log(
  "path.resolve() : ",
  path.resolve(__dirname, "..", "users", ".", "/zerocho")
);

@콘솔출력값
$ node part3/path

path.sep :  /
path.delimiter :  :
---------------------------
path.dirname() :  /Users/parkchaeeun/project/playground-cepark/part3
path.extname() :  .js
path.basename() :  path.js
path.basename - extname :  path
---------------------------
path.parse() :  {
  root: '/',
  dir: '/Users/parkchaeeun/project/playground-cepark/part3',
  base: 'path.js',
  ext: '.js',
  name: 'path'
}
path.format() :  C:\users\zerocho/pathjs
path.normalize() :  C:/users\\zerocho\path.js
---------------------------
path.isAbsolute(C:\) :  false
path.isAbsolute(./home) :  false
---------------------------
path.relative() :  ../C:\
path.join() :  /Users/parkchaeeun/project/users/zerocho
path.resolve() :  /zerocho

 

  • path.sep
    : 경로 구분자 
  • path.delimiter
    : 환경 변수 구분자
  • path.dirname(경로)
    : 파일이 위치한 폴더 경로를 보여줌
  • path.extname(경로)
    : 파일 확장자를 보여줌
  • path.basename(경로, 확장자)
    : 파일의 이름 (확장자 포함)을 표시, 파일의 이름만 표시하고 싶다면 basename의 두 번째 인수로 파일의 확장자를 넣어줌
  • path.parse(경로)
    : 파일 경로를 root, dir, base, ext, name으로 분리
  • path.format(객체)
    : path.parse()한 객체를 파일 경로로 합침
  • path.normalize(경로)
    : /나 \를 실수로 여러 번 사용했거나 혼용했을 때 정상적인 경로로 변환
  • path.isAbsolute(경로)
    : 파일의 경로가 절대경로인지 상대경로인지를 true/false로 알림
  • path.relative(기준 경로, 비교 경로)
    : 경로를 두 개 넣으면 첫 번째 경로에서 두 번째 경로로 가는 방법을 알려줌
  • path.join(경로, ...)
    : 여러 인수를 넣으면 하나의 경로로 합침
  • path.resolve(경로, ...) 
    : path.join()과 비슷하지만 차이가 있음. 아래 참고

 

✱ path.join과 path.resolve의 차이

/ 를 만나면 path.resolve는 절대 경로로 인식해서 앞의 경로를 무시하지만,

path.join은 상대 경로로 처리합니다.

path.join('/a', '/b', 'c'); // 결과 : /a/b/c/
path.resolve('/a', '/b', 'c'); // 결과 : /b/c

 

url

 

  • 인터넷 주소를 쉽게 조작하도록 도와주는 모듈
  • WHATWG 방식을 이용

 

url.js

const url = require("url");

const { URL } = url;
const myURL = new URL(
  "https://chanychu.tistory.com/manage/newpost/?type=post&returnURL=%2Fmanage%2Fposts%2F#anchor"
);
console.log("new URL() : ", myURL);
console.log("url.format() : ", url.format(myURL));

@콘솔출력값
$ node part3/url

new URL() :  URL {
  href: 'https://chanychu.tistory.com/manage/newpost/?type=post&returnURL=%2Fmanage%2Fposts%2F#anchor',
  origin: 'https://chanychu.tistory.com',
  protocol: 'https:',
  username: '',
  password: '',
  host: 'chanychu.tistory.com',
  hostname: 'chanychu.tistory.com',
  port: '',
  pathname: '/manage/newpost/',
  search: '?type=post&returnURL=%2Fmanage%2Fposts%2F',
  searchParams: URLSearchParams { 'type' => 'post', 'returnURL' => '/manage/posts/' },
  hash: '#anchor'
}
url.format() :  https://chanychu.tistory.com/manage/newpost/?type=post&returnURL=%2Fmanage%2Fposts%2F#anchor

URL 생성자에 주소를 넣어 객체로 만들면 주소가 부분별로 정리 되는 것을 확인할 수 있습니다.

해당 방식이 WHATWG의 url

 

  • url.format(객체)
    : 분해되었던 url 객체를 다시 원래 상태로 조립

주소가 host 부분 없이 pathname 부분만 오는 경우, new URL(pathname, host)로 처리해야 WHATWG 방식을 사용할 수 있습니다.

 

searchParam.js

const myURL = new URL(
  "http://www.gilbut.co.kr/?page=3&limit=10&category=nodejs&category=javascript"
);
console.log("searchParams : ", myURL.searchParams);
console.log("searchParams.getAll() : ", myURL.searchParams.getAll("category"));
console.log("searchParams.get() : ", myURL.searchParams.get("limit"));
console.log("searchParams.has() : ", myURL.searchParams.has("page"));

console.log("searchParams.keys() : ", myURL.searchParams.keys());
console.log("searchParams.values() : ", myURL.searchParams.values());

myURL.searchParams.append("filter", "es3");
myURL.searchParams.append("filter", "es5");
console.log(myURL.searchParams.getAll("filter"));

myURL.searchParams.set("filter", "es6");
console.log(myURL.searchParams.getAll("filter"));

myURL.searchParams.delete("filter");
console.log(myURL.searchParams.getAll("filter"));

console.log("searchParams.toString() : ", myURL.searchParams.toString());
myURL.search = myURL.searchParams.toString();

@콘솔출력값
$ node part3/searchParams

searchParams :  URLSearchParams {
  'page' => '3',
  'limit' => '10',
  'category' => 'nodejs',
  'category' => 'javascript' }
searchParams.getAll() :  [ 'nodejs', 'javascript' ]
searchParams.get() :  10
searchParams.has() :  true
searchParams.keys() :  URLSearchParams Iterator { 'page', 'limit', 'category', 'category' }
searchParams.values() :  URLSearchParams Iterator { '3', '10', 'nodejs', 'javascript' }
[ 'es3', 'es5' ]
[ 'es6' ]
[]
searchParams.toString() :  page=3&limit=10&category=nodejs&category=javascript

myURL.searchParams 대신 new URLSearchParams(myURL.search)로도 같은 결과를 얻을 수 있습니다.

 

  • getAll(키)
    : 키에 해당하는 모든 값을 가져옴
  • get(키)
    : 키에 해당하는 첫 번째 값만 가져옴
  • has(키)
    : 해당 키가 있는지 없는지 검사
  • keys()
    : searchParams의 모든 키를 반복기 객체로 가져옴
  • values()
    : searchParams의 모든 값은 반복기 객체로 가져옴
  • append(키, 값)
    : 해당 키를 추가, 같은 키의 값이 있다면 유지하고 하나 더 추가
  • set(키, 값)
    : append와 비슷하지만 같은 키의 값들을 모두 지우고 새로 추가
  • delete(키)
    : 해당 키 제거
  • toString()
    : 조작한 searchParams 객체를 다시 문자열로 만듦, search에 해당 문자열을 대입하면 주소 객체에 반영

 

dns

 

  • 도메인을 통해 IP나 기타 DNS 정보를 얻고자 할 때 사용

dns.mjs

import dns from "dns/promises";

const ip = await dns.lookup("gilbut.co.kr");
console.log("IP : ", ip);

const a = await dns.resolve("gilbut.co.kr", "A");
console.log("A", a);

const mx = await dns.resolve("gilbut.co.kr", "MX");
console.log("MX", mx);

const cname = await dns.resolve("www.gilbut.co.kr", "CNAME");
console.log("CNAME", cname);

const any = await dns.resolve("gilbut.co.kr", "ANY");
console.log("ANY", any);

@콘솔출력값
$ node part3/dns.mjs  

IP :  { address: '49.236.151.220', family: 4 }
A [ '49.236.151.220' ]
MX [
  { exchange: 'alt2.aspmx.l.google.com', priority: 5 },
  { exchange: 'aspmx2.googlemail.com', priority: 10 },
  { exchange: 'aspmx.l.google.com', priority: 1 },
  { exchange: 'alt1.aspmx.l.google.com', priority: 5 },
  { exchange: 'aspmx3.googlemail.com', priority: 10 }
]
CNAME [ 'slb-1088813.ncloudslb.com' ]
ANY [
  { value: 'ns1-2.ns-ncloud.com', type: 'NS' },
  { value: 'ns1-1.ns-ncloud.com', type: 'NS' },
  {
    nsname: 'ns1-1.ns-ncloud.com',
    hostmaster: 'ns1-2.ns-ncloud.com',
    serial: 45,
    refresh: 21600,
    retry: 1800,
    expire: 1209600,
    minttl: 300,
    type: 'SOA'
  }
]

 

  • dns.lookup, dns.resolve(도메인)
    : ip 주소
  • A
    : ipv4 주소
  • AAAA
    : ipv6 주소
  • NS
    : 네임서버
  • SOA
    : 도메인 정보
  • CNAME
    : 별칭
  • MX
    : 메일 서버

 

crypto

 

  • 다양한 방식의 암호화를 도와주는 모듈
  • 고객의 비밀번호는 반드시 암호화가 필요

 

단방향 암호화 (해시 함수)

- 비밀번호는 보통 단방향 암호화 알고리즘을 사용해 암호화

- 복화할 수 없는 암호화 방식을 뜻함 (복호화 : 원래 문자열로 되돌려놓는 것)

- 주로 해시 기법을 사용 (해시 기법 : 어떠한 문자열을 고정된 길이의 다른 문자열로 바꾸는 방식)

 

hash.js

const crypto = require("crypto");

console.log(
  "base64 : ",
  crypto.createHash("sha512").update("비밀번호").digest("base64")
);

console.log(
  "hex : ",
  crypto.createHash("sha512").update("비밀번호").digest("hex")
);

console.log(
  "base64 : ",
  crypto.createHash("sha512").update("다른 비밀번호").digest("base64")
);

@콘솔출력값
$ node part3/hash   

base64 :  dvfV6nyLRRt3NxKSlTHOkkEGgqW2HRtfu19Ou/psUXvwlebbXCboxIPmDYOFRIpqav2eUTBFuHaZri5x+usy1g==
hex :  76f7d5ea7c8b451b773712929531ce92410682a5b61d1b5fbb5f4ebbfa6c517bf095e6db5c26e8c483e60d8385448a6a6afd9e513045b87699ae2e71faeb32d6
base64 :  cx49cjC8ctKtMzwJGBY853itZeb6qxzXGvuUJkbWTGn5VXAFbAwXGEOxU2Qksoj+aM2GWPhc1O7mmkyohXMsQw==

비밀번호라는 문자열을 해시를 사용해 바꾸었습니다.

 

  • createHash(알고리즘)
    : 사용할 해시 알고리즘을 넣음. md5, sha1, sha256, sha512 등 가능하지만, 현재는 sha512로 충분
  • update(문자열)
    : 변환할 문자열을 넣음
  • digest(인코딩)
    : 인코딩할 알고리즘을 넣음. base64, hex, latin1이 주로 사용되는데 , base64가 결과 문자열이 가장 짧아 애용
    변환된 문자열을 반환해줌

하지만, 가끔 서로 다른 문자열이 동일한 문자열로 변환되어 충돌이 되는 경우가 있습니다.

이러한 상황과 더욱 더 강력한 암호화를 위해 pbkdf2나 bcrypt, scrypt 알고리즘으로 비밀번호를 암호화합니다. (salt 처리)

 

pbkdf2.js

const crypto = require("crypto");

crypto.randomBytes(64, (err, buf) => {
  const salt = buf.toString("base64");
  console.log("salt : ", salt);
  crypto.pbkdf2("비밀번호", salt, 100000, 64, "sha512", (err, key) => {
    console.log("password : ", key.toString("base64"));
  });
});

@콘솔출력값
$ node part3/pbkdf2

salt :  KTqBS0xOoP1mzCB62dQDXtdTmG9RvxJj9gvDlSbi6z1t2ZxReVBIKNUcZVzr4Ps2hkcpIfZJiv5uHa9bU6kjkQ==
password :  R3GP0Xr7K94fh/gV0pYruV783DCn1nJ4k3YO/G35nMzpXDnKA6bUpCMQO0efD1x62qdDnFm941E6REUdPQ54sg==