본문 바로가기

WEB/Javascript

[JS][Node.js] http을 이용해 서버 만들기 - 서버만들기 / 쿠키만들기

* 본 게시글은

'Node.js 기본 교과서 ' - 조현영 지음 

책을 참조했습니다.

 

요청 (request) 과 응답 (response) 

 

1. 서버 만들기 

1. http 모듈을 불러온다

const http = require('http')

2. 서버를 생성한다.

const server = http.createServer((rep,res)=>{
})

server.listen(8080)
server.on('listening',()=>{
    console.log('waiting in 8080')
})

 

2-1. 서버내용을 직접 작성

const server = http.createServer((req,res)=>{
    res.wirte('<h1>Hello!!</h1>')
    res.end('<p>Node,js!</p>')
})

server.listen(8080)
//포트 8080번으로 프로세스를 구분한다. 21/80/443 등 다른 번호들이 있다.
server.on('listening',()=>{
    console.log('8080에서 서버 대기중')
})

server.on('error',(error)=>[
    console.error(error)
])

 

node.js에서 작성한 웹

2-2 . fs을 이용해서 html파일 읽어오기

const http = require('http')
const fs = require('fs')

const server= http.createServer((req,res)=>{
    fs.readFile('./index.html',(err,data)=>{
        if (err){
            throw err
        }
        res.end(data)
    })
})
server.listen(8080)
server.on('listening',()=>{
    console.log('waiting in 8080 ')
})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>HELLO</h1>
    <h2>Node.js Web Server</h2>
    <p>practicing</p>
</body>
</html>

html파일을 불러옴

 

2. 쿠키로 사용자 식별하기

클라이언트 요청을 누가 보냈는지 알기 위해서 로그인을 구현할 수 있다.

서버는 요청에 대한 응답을 할 때 쿠키도 같이 보낸다. 

쿠키 : 키-값

 

요청과 응답은 각각의 헤더(header)본문(body)을 가지며 쿠키는 헤더(header)에 저장된다.

 

1. 쿠키 만들기

 

1-1. 쿠키 패싱 함수 만들기

const parseCookies = (cookie='') =>
    cookie
    .split(';')
    .map(v=>v.split('='))
    .map(([k, ... vs])=>[k,vs.join('=')])
    .reduce((acc,[k,v])=>{
        acc[k.trim()]=decodeURIComponent(v)
        return acc
    },{})

cookie =

'name=taeyu;date=20220727'  와 같은 문자열을

{ name : 'taeyu' , date : '20220727' } 와 같은 객체로 바꾸는 함수 

 

1-2. 쿠키 가져오기 req.headers.cookie

const cookies = parseCookies(req.headers.cookie)

1-3. 가져온 쿠키를 응답에 기록한다 res.writeHead(상태코드,{'브라우저에게쿠키':'쿠키내용 키=값'})

const server= http.createServer((req,res)=>{
    const cookies = parseCookies(req.headers.cookie)
    console.log(req.url, cookies)
    res.writeHead(200,{'Set-Cookie':'mycookie=test'})
    fs.readFile('./index.html',(err,data)=>{
        if (err){
            throw err
        }
        res.end(data)
    })
})

res.writeHead(상태코드,{'브라우저에게쿠키':'쿠키내용 키=값'})

'Set-Cookie'은 브라우저에게 같은 값의 쿠키를 설정하라는 뜻이므로 

값인 'mycookie=test'가 위의 패싱함수를 걸쳐 cookies 할당되어 { mycookie: 'test' } 로 콘솔에 나타난다.

 

처음 노드를 실행했을 때는 아직 쿠키가 없어 빈 객체 나왔고

 

브라우저가 favicon에 대해 html파일에서 알수 없으면 서버에게 이에 대한 정보를 요청한다.

따라서 추가로 요청을 보낸 것이 쿠키와 함께 콘솔에 출력되었다.

 

 

2. 쿠키로 식별하기

 

사용한 html

    <form action="/login">
        <input name="name" id="name" placeholder="이름을 입력"/>
        <button id="login">이름으로 로그인</button>
    </form>

 

2-1 . 필요한 모듈 불러오기

const http = require('http')
const fs = require('fs')
const url =require('url')
const querystring =require('querystring')

2-2. 사용자가 로그인버튼을 누른 경우 :  req.url.startsWith('/login')인 경우

const server= http.createServer((req,res)=>{
    const cookies = parseCookies(req.headers.cookie)

    if(req.url.startsWith('/login')){
        const { query }=url.parse(req.url)
        const { name }=querystring.parse(query)
        const expires = new Date()
        expires.setMinutes(expires.getMinutes()+1)
        res.writeHead(302,{
            Location:'/',
            'Set-Cookie':`name=${encodeURIComponent(name)};Expires=${expires.toGMTString()};HttpOnly;Path=/;`
        }) //줄바꿈 설정을 조심하자 오류의 원인
        res.end()
    }
})

 

req.url : /login?name=입력할이름

query : name=입력할이름

name : 입력할이름

 

res.writeHead(상태코드: 302 리디렉션

{Set-Cookie에 Expires을 Wed, 27 Jul 2022 06:43:46 GMT와 같은 형식으로 변경했다

expires에 값이 할당 된 시간에 1분이 지난 Wed, 27 Jul 2022 06:43:46 GMT 때에 유효기간이 끝난다는 것이다.})

 

2-3 . 로그인 후 name=입력한 이름인 경우  : /login?name=입력한이름

 

    else if (cookies.name){
        res.writeHead(200,{'Content-Type':'text/html; charset=utf-8'})
        res.end(`${cookies.name}님 안녕하셔유🫡`)

2-4. 메인 홈페이지( 요청이 없었을 경우)

    else{
            fs.readFile('./index2.html',(err,data)=>{
                if (err){
                    throw err
                }
                res.end(data)
            })
        }

 

2-5.  보안을 위해 세션에 저장하기

세션을 객체로 나타내서

const session = {}

임의의 수로 세션을 구분하고 사용자 정보를 저장한다.

        const randomInt = Date.now()
        session[randomInt]={
            name,
            expires,
        }

헤더 작성시는 임의의 수를 키값으로 저장하고

'Set-Cookie':`session=${randomInt}`

로그인하였을 경우 유효기간이 안되었을 동안에

사용자 이름을 가져와 띄운다.

    else if (cookies.session && session[cookies.session].expires > new Date()){
        res.writeHead(200,{'Content-Type':'text/html; charset=utf-8'})
        res.end(`${session[cookies.session].name}님 안녕하셔유🫡`)
    }