본문 바로가기
더이상 하지 않는 Backend - NodeJS/Node-Express 개론(완)

[O'REILLY] Node & Express - 9장 : 쿠키와 세션

by VictorMeredith 2023. 4. 3.

1. 들어가면서

- HTTP는 상태가 없는 프로토콜이다. 상태가 없다는 것은 브라우저에서 어떤 페이지를 불러온 다음, 같은 웹사이트의 다른 페이질 이동할 때 같은 브라우저가 같은 사이트에 방문한다는 사실을 알아낼 방법이 없다는 것이다.

- 모든 HTTP 요청에는 서버에서 요청을 수행할 때 필요한 정보가 모두 들어있다는 뜻이다.

- 이를 해결하기 위해 '상태'를 보존할 방법이 필요했고, 쿠키와 세션이 등장했다.

 

2. 쿠키에 대해서

- 사용자가 쿠키 내용을 볼 수 있다.

- 사용자가 쿠키를 삭제하거나 금지할 수 있다. : 사용자는 쿠키 전체에 대한 권한이 있다. 사용자가 쿠키를 금지할 경우, 웹앱에서 많은 기능이 제약될 수 있다.

- 일반적인 쿠키는 변조될 수 있다. : 서명된 쿠키를 사용해야 한다.

- 쿠키는 공격에 사용될 수 있다. : XXS공격중에는 악의적인 JS코드로 쿠키 콘텐츠를 바꾸는 방법이 있다. 쿠키 변경은 서버에서만 가능하게끔하는 설정도 있다. 이를 사용하면 조금 더 보안에 이점이 있다.

- 쿠키를 남용하면 사용자가 눈치챈다. 최소한으로 유지해야한다.

- 가급적 쿠키보다 세션을 사용한다. : 이건 사용자특성, 웹사이트/웹앱의 요구사항, 기능 등 다양한 상황에 따라서 다른데, 일반적으로 쿠키보다 세션이 보안에 우세한 경우가 많고, 현대의 보안이 중요한 웹사이트들은 쿠키와 세션 모두 다 사용한다.

 

3.  자격 증명 위임

- 쿠키 보안을 위해서는 쿠키 시크릿이 필요하다. 

- 쿠키시크릿 : 서버에서 쿠키를 클라이언트에 보내기 전에 암호화할 때 사용하는 문자열이다. 

- 이 목적에 맞게 자격 증명은 JSON 파일에 담아서 외부화한다. 

- 실무용, 테스트용, 기타용도에 맞게 자격 증명 파일을 따로 유지한다.

- 당연히 .gitignore 에 해당 파일을 추가하고 저장소에 공유되는 일이 없도록 보안에 신경을 써준다.

 

4. Express 와 Cookie

- 앱에서 쿠키를 사용하려면 cookie-parser 미들웨어를 추가해야한다.

 

설치

npm i cookie-parser

 

미들웨어

옵션에서 쿠키시크릿을 추가할 수 있다.

- cf) 서명된 쿠키는 일반적인 쿠키보다 우선순위가 높다. 서명된 쿠키에 이름이 붙여져있다면, 같은 이름의 일반 쿠키는 사용할 수 없다.

 

jwt(JSON Web Token)을 이용한 cookie-based Auth 구현 예시

클라이언트는 req.headers.cookie에 자동으로 jwt를 넣어 요청하게 된다. 서버는 이를 받아서 로직만 구현하면 된다.

 

쿠키에서 사용할 수 있는 옵션들

- domain : 쿠키에 도메인을 연결한다. 즉, 특정 서브도메인에 쿠키를 할당한다. 현재 서버가 실행 중인 도메인이 아닌 다른 도메인과 연결할 수는 없다.

- path : 쿠키가 적용될 경로를 지정한다. 암시적인 와일드카드가 적용된다. 경로에 기본값인 /를 사용하면 사이트의 모든 페이지에 쿠키가 적용된다.

- maxAge : 클라이언트가 쿠키를 얼마나 오래 보관하고 있어야 하는지 밀리초 단위로 지정한다. 이 옵션을 설정하지 않으면 브라우저를 닫을 때 쿠키가 삭제된다. expires 옵션에서 만료날짜를 설정할 수 있긴하지만, maxAge를 쓰는 사람도 있다.

- secure : 이 옵션을 설정하면 보안(HTTPS) 연결을 통해서만 쿠키를 전송한다.

- httpOnly : 이 옵션을 true로 설정하면, 서버에서만 쿠키를 수정한다. 클라이언트 사이드 JS는 쿠키를 수정할 수 없다. XSS 공격 방어에 도움이 된다.

- signed : 이 옵션을 true로 설정하면, 쿠키에 서명을 해서 res.cookie가 아니라 res.signedCookies에서 접근할 수 있게 한다. 서명된 쿠키가 변조된다면 서버는 그 쿠키를 거부하고 원래 값으로 초기화한다.

 

5. Express와 Session

- 세션은 상태를 좀 더 쉽게 관리하는 수단이다.

- 세션을 사용하기 위해서는 클라이언트에 뭔가를 저장해야한다. 일반적으로 쿠키에 고유한 식별자를 담아서 사용한다.

- HTML5 에서는 로컬 스토리지를 도입했다. 이를 통해 뭔가를 할 수도 있다.

- 쿠키기반세션 : 모든 정보를 쿠키에 저장하는 방법. 장점이 그닥 없다. 세션 정보를 서버에 저장하는 것을 추천한다. 

- 서버저장세션 : 쿠키에 고유 식별자만 저장하고, 나머지 정보는 모두 서버에 저장하는 방법이다. 세션이라고 하면 보통 이걸 말한다.

 

메모리 세션

- 메모리 세션은 사용하기 쉽지만, 서버 재시작의 경우 세션 정보가 모두 사라진다. 더 심각한 단점은, 여러 대의 서버로 확장할 때 매 요청을 서로 다른 서버에서 서비스할 수 있다는 점이다. 이런 상황에서 사용자 요청에서 세션 데이터가 어느 서버에는 없을 수도 있게되며, 매우 혼란스러워진다. 하지만 메모리세션은 개발테스트목적으로는 충분하다.

 

설치

npm i express-session

 

미들웨어 작성

옵션들

- resave : 요청이 수정되지 않았더라도 세션을 강제로 저장한다. 일반적으로 false가 좋다.

- saveUninitialized : true로 설정하면, 새로운 세션을,. 수정되지 않았더라도 강제로 저장한다. 일반적으로 false로 두는 게 좋으며, GDPR에서는 반드시 false로 두어야 한다.

- secret : 세션 ID 쿠키에 서명할 때 사용하는 키. cookie-parser에서 사용하는 키와 같아도 된다.

- Key : 고유한 세션 식별자를 저장할 쿠키의 이름. 기본값은 connect.sid

- store : 세션 저장소 인스턴스. 기본값은 MemoryStore의 인스턴스이다.

- cookie : 세션 쿠키에 적용할 설정(path, domain, secure). 일반 쿠키의 기본값이 적용된다.

 

세션 사용하기

- 요청 객체의 session 변수의 프로퍼티를 사용하면 된다.

참 쉽죠?

- 세션을 사용하면 요청 객체에서 값을 가져오고 응답객체에서 값을 설정할 필요 없이 전부 요청객체에서 처리한다.

- 세션을 삭제할 때는 js의 delete연산자를 사용한다.

delete req.session.colorShceme //삭제

 

세션의 활용

- 여러 페이지에 적용되는 사용자 설정을 저장할 때 유용하다.

- 사용자 인증 정보를 보관할 때 가장 널리 사용된다.

- 로그인할때 세션이 만들어져서 저장이되면, 새로고침이 될 때마다 다시 로그인할 필요가 없어진다.

- 선호 정렬 방식, 날짜 표시 형식을 저장할 경우에도 널리 쓰인다.

- 세션과 쿠키를 적절히 활용하면 더 좋다.

 

댓글