카테고리 없음

Cookie, Session ( node.js, express, ejs )

DevOhwa 2022. 8. 13. 22:57
반응형

220812 

갓규리쌤의 수업을 바탕으로 작성되었습니다. 

 

 

Cookie 란?

웹 브라우저(클라이언트)에 저장되는 키와 값이 들어있는 작은 데이터 파일이다. 이름, 값, 만료일, 경로 정보로 구성되어있다. 

쇼핑몰 등의 사이트에서 팝업으로 뜨는 '오늘 하루동안 보지않기' 등의 창이 우리가 쉽게 볼 수 있는 쿠키라고 생각하면 쉽다. 

⇒ console에서 Application으로 가면 cookies를 확인 할 수 있다. 

 

 

Cookie의 동작 방식

클라이언트가 페이지를 요청

→ 서버에서 쿠키 생성

→ HTTP 헤더에 쿠키를 포함시켜 응답

→ 브라우저가 종료되어도 쿠키만료 기간이 있다면 클라이언트에서 보관하고 있음

→ 같은 요청을 할 경우 HTTP 헤더에 쿠키를 함께 보냄

→ 서버에서 쿠키를 읽어 이전 상태 정보를 변경 할 필요가 있을 때 쿠키를 업데이트하여 변경된 쿠키를 HTTP헤더에 포함시켜 응답

 

참고로 헤더는 utf파일같은거 설정하거나 .json등의 정보를 담고있는게 헤더이다. Network에서 확인가능하다. 어떻게 통신하고 응답받았는지 확인 할 수 있다. 

 

쿠키의 만료기간이 없으면 브라우저가 종료될때 쿠키가 사라지고, 만료기간이 있다면 만료 기간까지 클라이언트에서 쿠키를 보관하고 있다. 

ex) 하루동안 보지 않겠습니다. 등의 시간 설정.

쿠키는 데이터 파일이므로 읽고, 수정하고, 삭제하는것들이 다 가능하다. 

 

 

Cookie 의 사용예시

팝업창 하단에 볼 수 있는 '오늘 그만보기' 나 쇼핑몰이나, 검색사이트 등의 로그인 유지도 쿠키를 사용하는 예시라고 볼 수 있다.

 

 

Cookie 사용하기

init, ejs와 express만 설치하면 된다.

- index.js와 views 폴더를 만들어준다. 

 

<index.js>

const express = require('express');
const app = express();

app.set('view engine', 'ejs');

app.get('/', (req,res) => {
	res.render("index");
});

app.listen(8000, () => {
	console.log('sercer : ', 8000):
});

HTTP때는 헤더를 따로 설정했어야했다. 근데 expresss는 res객체에 쿠키가 있다. 알아서 헤더에 담아서 보내준다. 

 

 

npm i cookie-parser 설치후에 index에 불러온다. 

const cookieParser = require("cookie-parser");

 

호스트로 바디를 받도록 하겠습니다는 app.use이다. app.use(cookieParser());는 쿠키를 이용하겠다고 적어주는것이다. 위에 뜨는 팝업에 secret은 사용할 비밀키를 작성해달라고 뜨는것이다. 

어떻게해서 비밀키가 작동되는지(?) 궁금하면 node.js 홈페이지 가서 확인하면 된다. 

 

 

 res.cookie('key', 'value');로 쿠키를 보내준다. 이름에 key들어가고, 값에 value들어간다.

만일 로컬에서 쿠키를 설정하면 서버까지 안거쳤기 때문에 쿠키는 사라진다. 

 

const express = require("express");
const cookieParser = require("cookie-parser");
const app = express();


app.set("view engine", "ejs");
app.use(cookieParser('1234'));


const cookieConfig = {
//cookieConfig는 키, 밸류 외에 설정을 보낼 수 있다.
	maxAge : 30000,
    //밀리초 단위로 들어가는데 30000을 설정하면 30초만료 쿠키를 생성한다. 
    path: '/',
    httpOnly: true,
    //통신할때만 접속할 수 있다. 기본값은 false임 
    signed: true,
    //쿠키를 암호화 시킨다. 
};

app.get("/", (req,res) => {
    req.session.name = "홍길동";
    res.cookie('key', 'value', cookieConfig);
    res.render("index");
});

app.listen(8000, ()=>{
    console.log( "Server : ", 8000 );
});

→ Expire가 날짜로 바뀌어있음을 볼 수 있다. 30초가 지나면 쿠키는 사라진다. 

 

app.get("/get", (req,res) => {
    console.log(req.cookies);
    res.send(req.cookies);
    //req가 클라이언트가 서버한테 요청하는것임. 어떤 요청인지 궁금하면console.log(Req)로 확인하면됨
})

→ 쿠키 어떤거 있는지 보여주는것이다. 근데 클라이언트한테 있는 쿠키를 보여주는거니까 클라이언트한테 받기 위해서 req.cookies이다. 

 

 

<views 폴더 - cookie.ejs >

app.get("/cookie", (req,res)=> {
    res.render("cookie");
})

→ "/cookie" 경로에 접속하면 cookie.ejs 파일을 불러와서 보여준다.(랜더링 해준다.)

 

<cookie.ejs>

<html>
    <head>
        <script>
            console.log(document.cookie);
        </script>
    </head>
</html>

→ 쿠키를 확인 할 수 있다. document.cookie에 쿠키 정보가 담긴다. 

 

 

<html>
    <head>
        <script>
            console.log(document.cookie);
            document.cookie = "user=sesac; expires=Sat, 13 Aug 2022 13:00:00 GMT; path=/"; 
            console.log(document.cookie);
        </script>
    </head>
</html>

클라이언트에서 쿠키 설정⇒ user: sesac을 확인 할 수있다. 

 

<index.js> 

먼저 호스트(user=sesac)가고 그 다음에 쿠키가 가면 여러개의 쿠키가 연결되어 나오는것을 볼 수 있다. 

( 이부분 아무래도 user=sesac이라는 호스트가고 쿠키에서 key와 value가고 key2,value2 간다는것을 쓰고 싶었나본데 아니라면 수정을 해야겠다. )

위의 상황에서 cookie.ejs 는 아래와 같이 코드를 작성해서 확인 할 수 있다. 

<html>
    <head>
        <script>
            console.log(document.cookie);
        </script>
    </head>
</html>

 

만약 이럴때 key2의 값을 클라이언트가 갖고오고 싶다면 어떻게 해야할까.

<html>
    <head>
        <script>
            var cookieArr = document.cookie.split(";");
            // for (var i =0; i < cookieArr.length;i++ ) 와 아래 for문은 동일하다.
            //cookieArr가 갖고있는인덱스 만큼 도는것이다. 
            for( var i in cookieArr ){
                console.log(cookieArr[i]);
            }

            
        </script>
    </head>
</html>

;으로 split 하고 for문 돌면서 key가 key2인 친구를 찾아야한다. 

(와우.. 뭐라는건지 지금보니까 모르겠다... 나중에 이해하는대로 추가)

그런데 이렇게 for문을 설정하면 만료기한 등의 옵션을 설정할 수 없다.  

 

 

<html>
    <head>
        <script>
            console.log(document.cookie);
            document.cookie = "user=sesac; expires=Sat, 13 Aug 2022 13:00:00 GMT; path=/";

→ 위와 같은 형태로 명확하게 날짜를 적어주어야한다. 만일 path등의 다른 옵션을 지정하고 싶다면 ;으로 나눠서 지정을 해주면 된다. 그럼 아래와 같이 내가 설정한 path /와 Expires가 나온다. 

 

 

(추가)

document.cookie로 쿠키는 여러개 생성할 수 없다. 텍스트 파일이니까 중간만 바꿀 수 없고, 수정하고 싶다면 다시 다 덮어써야한다. 

 

 

 

 

 

>>>

Session

session이란 웹 서버에 저장되는 쿠키이다. 

세션은 상태유지라고 보면된다. 한번 연결이 되면 그 상태를 계속해서 유지하는것이다. 연결을 끝낼때까지!

연결을 끝냈다 : 브라우저를 껐다.

쿠키보다 보안이 좋은 편이다. 쿠키는 클라이언트에 저장이 되기 때문에 우리가 볼 수 있는데, 세션은 서버에 저장이 되기 때문에 우리가 볼 수 없어서 보안이 좋다. 

쿠키는 저장에 제한이 있다. 그러나 세션은 서버에 저장하는거라 서버의 용량이 무한하다면 무한하게 저장 할 수 있다. 

 

 

Session의 동작 방식

클라이언트가 서버에 접속시 세션id를 발급받는다

→ 클라이언트는 세션id에 대해 쿠키를 사용해서 저장하고, 가지고 있다.

→ 클라이언트는 서버에 요청할 때, 이 쿠키의 세션 id를 서버에 전달해서 사용한다.

→ 서버는 세션 id를 전달받아서 별다른 작업 없이 세션 id로 세션에 있는 클라이언트 정보를 가져온다.

→ 클라이언트 정보를 가지고 서버 요청을 처리하여 클라이언트에게 응답한다. 

 

: 세션은 서버에서 만들어진다. 아이디만 클라이언트에게 보낸다. 키를 보내고 값은 클라이언트가 모른다. 

클라이언트가 요청할 때 서버가 키를 가지고 찾아서 값을 보내주는 것이다.  

 

 

Cookie and Session

쿠키와 세션은 저장되는곳이 다르다. 

가장 큰 차이점은 속도이다. 우리눈으로 확인하기는 어렵지만, 실제로 쿠키가 조금 더 빠르다. 클라이언트에 저장이 되어있기 때문에 바로 저장한것을 가져와서 사용 할 수있다. 서버에 요청하지 않아도 된다.

반면, 세션은 서버 아이디를 기반으로 찾아야하기 때문에 몇단계를 거쳐야하므로 세션이 더 느리다. 

 

 

 

Session사용하기

npm i express-session

설치해준다.

 

 

<index.js>

app.get("/", (req,res) => {
    req.session.name = "홍길동";
    res.cookie('key', 'value', cookieConfig);
    res.cookie('key2', 'value2', cookieConfig);
    res.render("index");
});

app.get("/get", (req,res) => {
    console.log( req.session.name);
    console.log(req.cookies);
    res.send(req.cookies);
})

/get으로 가면 console에 홍길동이 뜨고, 다른페이지를 가도 계속 유지가 됨을 확인 할 수 있다. 

세션은 연결된 상태를 유지하면서 값이 저장되는 거라서 연결이 끊기면 저장된 값이 사라진다. 브라우저를 끔으로써 연결을 끄는 것이다. 그렇기 때문에 브라우저를 끄면 네임에 저장된 홍길동이 console 에서 사라진다. 

 

app.get("/destroy", (req,res)=> {
    // res.render("cookie");
    req.session.destroy(function(err){
        res.send("삭제");
    })
    req.session.name = "";
    
})

destroy는 모든 정보를 한번에 지워준다. (초기화)

get → destroy에서 삭제하고, 다시 get으로 오면 세션이 지워졌음을 확인 할 수있따. 세션이 저장되어있던걸 모두 다 없애준것이다. 

 

 

근데 내가 하나만 없애고 싶다면? 값을 빈값으로 따로 설정해 주어야한다.

req.session.name = "";

하나만 삭제하고 싶은것은 그때 그 값이 빈값이 되도록 설정해주면 된다. 

 

<index.js>

app.get("/", (req,res) => {
    req.session.key = "value";
    req.session.name = "1";
    req.session.num = "2";
    res.cookie('key', 'value', cookieConfig);
    res.cookie('key2', 'value2', cookieConfig);
    res.render("index");
});

localhost:nnnn/get으로 가고, 그 후 localhost:nnnn/distroy를 가준다. 

그리고 /get을 가보면 세션이 비어있음을 확인 할 수있다. 

 

app.get("/destroy", (req,res)=> {
    req.session.name = "";
    res.send("123");
})

req.session.name = ""; 해주고 위와같이 get - distroy - get으로 가면, name 이 비어있다. 

 

 

<index.js>

//로그인 페이지 보이겠지 버튼 눌렀을때 포스트 ~!
app.get("/login", (req,res) => {
    res.render("login");
});



//로그인 성공시 세션에 아이디 넣고 redirect:이동한다는것임 프로필로 했기때문에 그 get으로 가는것이다.
//폼정보를 보내준다
//검사 후 나온 결과가 flag라면 성공은 id 정보값을 제대로 넣은친구를 프로필페이지로 리다이렉트하는거임.
//프로필 redirect는 /profile로 우리가 치는거랑 다음. 실패시 다시 로그인페이지가 보이는것이다.
app.post("/login", (req,res) => {
    var flag = true;
    if (flag) {
        req.session.id = req.body.id;
        res.redirect("/profile");
    }else res.redirect("/login");
});

app.get("/profile", (req,res) => {
    if (req.session.id == undefined || req.session.id ==""){
        res.redirect("/login");
        return false;
    }
    req.session.id
    res.render("profile");
});

app.get("/main", (req,res) => {

});


app.listen(8000, ()=>{
    console.log( "Server : ", 8000 );
});

만약 세션에 아이디가 없거나 비어있으면 이 사람은 로그인 성공자가 아니다. 그러므로 로그인으로 redirect 보낸다.

근데 정상이면 그 아이디를 가지고, db검색이나 프로필정보를 가져온다. render 프로필정보를 볼 수있게 되는것이다. 지금까지 우리가 한건 프로필이 무조건 post로 받았기 때문에 링크 접속은 can not post 됐던 것이다. 

위와같이 하면 로그인을 정상적으로 성공한사람이라면 /profile해도 볼 수 있다.

만약 내가 창을 껐다켜서 아이디 undifined 나오면 로그인부터 하라고 다시 로그인페이지로 간다. 

 

 

분명 수업때는 다 이해간줄알았는데, 보니까 아닌거같다.. 내가 쓰고도 이해안가는게 태반이다. 프로젝트에 세션을 잘 사용 할 수 있을까.. 

 

 

 

 

*피드백받아서 수정되었습니다. 왕감사!!