Expiration and Secrets

쿠키의 property에 대해 알아보도록 한다.

Name,Value,Domain,Path,Expires / Max-Age가 있다.

그리고 Size,HttpOnly,Secure,SameSite,Priority등이 있다.

우선 가장 중요한 것들부터 다뤄본다.

첫번째는 secret이다.

secret은 쿠키에 sign할때 사용하는 string이다.

쿠키에 sign하는 이유는 백엔드가 쿠키를 줬다는걸 보여주기 위함이다.

왜냐하면 session hijack(납치)라는 공격유형이 있다.

이걸 잘 보호햐아 하는데 누군가 쿠키를 훔쳐서 마치 그 사람인척 할수 있다.

secret을 사용할 때에는 이 string을 사용하는데

이건 길게 작성되고 강력하고 무작위로 만들어야 한다.

string을 가지고 쿠키를 sign하고 만든 것임을 증명할 수 있기 때문이다.

다음으로 Domain이 있는데

Domain은 쿠키를 만든 백엔드가 누구인지 알려준다.

Instagram,Facebook,Google이 만든 쿠키는 없다.

브라우저는 Domain에 따라 쿠키를 저장하도록 되어있다.

그리고 쿠키는 Domain에 있는 백엔드로만 전송된다.

예를 들어서 localhost:4000에서 사용자에게 쿠키를 주었다.

그러니까 Domainlocalhost라고 적혀있고 어떤 요청을 하던간에

쿠키가 localhost로 전송 될거다.

그래서 localhostFacebook이나 YouTube의 쿠키를 받지 않는거다.

YouTube쿠키는 youtube.com으로 가고, 브라우저가 이 규칙을 지키는 거다.

그러니까 Domain은 쿠키가 어디에서 왔는지 어디로 가야하는지 알려주는거다.

path단순히 url이라 별거 아니고 중요한건 Expires이다.

보다시피 session이라고 적혀있다. 그러니까 이 쿠키는 만료날짜가 명시되지 않은거다.

https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/Set-Cookie

여길 보면 session cookie가 만료된다고 나와 있다.

만약 만료날짜를 지정하지 않으면 이건 session cookie로 설정되고

사용자가 닫으면 session cookie는 끝나게 된다.

예를 들어서 몇몇 브라우저에서 프로그램을 닫으면 쿠키가 사라지는 거다.

아니면 컴퓨터를 재시작할 때 세션이 사라지게 된다.

이건 사용자가 닫지 않는 한 계속 살아있는 거다.

이번엔 Max-Age를 알아본다.

Max-Age는 말그대로 언제 세션이 만료되는지 알려주는거다.

근데 백엔드를 자세히 봤다면 expires라는 만료날짜를 봤을거다.

그래서 브라우저가 평생 켜져있거나 사용자가 브라우저를 계속 켜놔도 백엔드에 만료날짜가 있다.

원한다면 이걸 바꿀수 도 있다. 한번 바꿔 본다.

server.js에서

app.use(
  session({
    secret: "Hello!",
    resave: false,
    saveUninitialized: false,
    cookie: {
      maxAge: 20000,
    },

maxAge는 쿠키가 얼마나 오래 있을수 있는지 알려주는거고 값은 1/1000초 단위로 쓰면 된다.

한번 20,000이라고 입력해본다. 그러면 20초일거다. 로그인해서 20초 기다린 다음

새로고침해서 정말 작동하는지 본다. 현재 브라우저 말고 다른 브라우저를 열어서

localhost:4000으로 간다. inspect를 열어 놓고 Application을 보면 아직 쿠키가 없다.

로그인을 해서 쿠키를 받았다. 이제 기다리면서 계속 새로고침을 할건데 로그인 되어있고 20초후에는

쿠키가 만료될거다. 결국에 만료 되었고 로그아웃 되었다. 쿠키가 사라졌기 때문이다.

이 설정으로 쿠키를 얼마동안 유지할지 정할수 있다. 다시 한번 로그인 해본다.

일단 만료날짜 없이 그냥 두도록 한다.

다음으로 URL을 보호해야 한다.

string도 마찬가지이다.

secret: "Hello!",

왜냐하면 코드에 다른 사람이 보면 안되는 값을 쓰면 안되는 거다.

예를 들어 secret이나 DB URL이 그럴수 있다.

이걸 위해 environment file(환경변수)를 만든다. src폴더 밖에다가 .env라고 만든다.

그리고 .gitignore안에 .env를 추가해야한다.

/node_modules
.env

왜냐하면 .env파일을 깃헙에 올리면 안되기 때문이다. .env에는 코드에 들어가면 안되는 값들을 추가한다.

설정 값 같은 것들을 말이다. 예를 들어 secret 이 있다.

코드에 secret을 넣고 싶지 않으니까 .env파일 안에 넣어준다.

그리고 관습적으로 env파일에 추가하는 모든건 대문자로 적어야 한다.

COOKIE_SECRET=asdlfjaslkdfj12345136356aljga
DB_URL=mongodb://127.0.0.1:27017/wetube

무작위하고 아무도 모르는 무언가로 쓰면 되고 숫자도 좀 넣어준다.

이게 바로 COOKIE_SECRET이다. 다른 걸로는 DB_URL이 있을거다.

env파일을 만들었고, 모든 API key나 모든 비밀로 해야하는 url을 넣어 줄거다.

모든걸 env파일 안에 추가하면 된다. 어떻게 env파일에 접근하면 될까?

process.env.DB_URL처럼 써주면 된다.

app.use(
  session({
    secret: process.env.COOKIE_SECRET,
    resave: false,
    saveUninitialized: false,
    store: MongoStore.create({ mongoUrl: process.env.DB_URL }),
  })
);

이렇게 해주면 된다. 그러면 콘솔을 한번 확인해 보도록 한다. 에러가 생겼다.

Error: Cannot init client. Please provide correct options
    at new MongoStore 

client를 초기화 할수 없다.

console.log(process.env.COOKIE_SECRET);

app.use(
  session({
    secret: process.env.COOKIE_SECRET,
    resave: false,
    saveUninitialized: false,
    store: MongoStore.create({ mongoUrl: process.env.DB_URL }),
  })
);

console.logCOOKIE_SECRET이 존재하는지 알아 본다.

undefined라고 뜬다. 지금까지 3분의 2정도 했다.

  1. env파일 만들기

  2. env파일을 .gitignore에 추가하기 .git에 업로드 하지 않을거라서 그렇다.

  3. 비밀로 해야하는 stringprocess.env(환경변수)로 바꾸기

db.js에서도 바꿔줘야 한다.

mongoose.connect(process.env.DB_URL, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

그리고 다음 파트에서 어떻게 이 DB_URLenv에서 읽을수 있는지 알아 보겠다.

좋은 웹페이지 즐겨찾기