http 헤더를 사용해 쿠키 옵션으로 표현할 수 있다.'Set-Cookie':[
'cookie=yummy',
'Secure=Secure; Secure',
'HttpOnly=HttpOnly; HttpOnly',
'Path=Path; Path=/cookie',
'Doamin=Domain; Domain=codestates.com'
]www.google.com과 같은 서버에 접속할 수 있는 이름이다.www 같은 도메인 앞에 추가로 작성되는 부분을 말한다.URL이 http://www.localhost.com:3000/users/login이라 하면 여기에서 Domain은 localhost.com이 된다.naver.com에서 받은 쿠키를 google.com에 전송하는 일을 막을 수 있다.Path는 세부 경로로써 서버가 라우팅할 때 사용하는 경로를 의미한다.URL이 http://www.localhost.com:3000/users/login인 경우라면 여기에서 Path, 즉 세부 경로는 /users/login이 된다./으로 설정되어 있다.Path 옵션의 특징은 설정된 경로를 포함하는 하위 경로로 요청을 하더라도 쿠키를 서버에 전송할 수 있다.Path가 /users로 설정되어 있고, 요청하는 세부 경로가 /users/codestates인 경우라면 쿠키 전송이 가능하다./posts/codestates로 전송되는 요청은 Path 옵션(/users)을 만족하지 못하기 때문에 서버로 쿠키를 전송할 수 없다.MaxAge는 쿠키가 유효한 시간을 초 단위로 설정하는 옵션이다.Expires는 MaxAge와 비슷하지만 언제까지 쿠키가 유효한지 심판의 날을 지정할 수 있다.MaxAge 또는 Expires 옵션이 없는 쿠키로, 브라우저가 실행 중일 때 사용할 수 있는 임시 쿠키이다. 브라우저를 종료하면 해당 쿠키는 삭제된다.MaxAge 또는 Expires에 지정된 유효시간만큼 사용가능한 쿠키이다.Secure 옵션이 true로 설정된 경우 HTTPS를 이용하는 경우에만 쿠키를 전송할 수 있다.Secure 옵션이 없다면 프로토콜에 상관없이 http://www.codestates.com 또는 https://www.codestates.com에 모두 쿠키를 전송할 수 있다.localhost인 경우에는 HTTPS가 아니어도 쿠키 전송이 가능하다.localhost를 사용하는 경우가 많기 때문에 생긴 예외이다.true로 설정된 경우, 자바스크립트로 쿠키에 접근이 불가하다.false로 지정된다.false인 경우 document.cookie를 이용해 자바스크립트로 쿠키에 접근할 수 있으므로 쿠키가 탈취될 위험이 있다.Cross-Site 요청을 받은 경우, 요청에서 사용한 메서드(e.g. GET, POST, PUT, PATCH …)와 해당 옵션의 조합을 기준으로 서버의 쿠키 전송 여부를 결정하게 된다.
이때, Cross-Origin과 Cross-Site를 혼동하지 않도록 주의해야 한다.
- Cross-Origin : 서버의 도메인, 프로토콜, 포트 중 하나라도 다른 경우
Cross-Origin으로 구분됩니다.
http://codestates.comvshttps://codestates.com⇒ 프로토콜이 다르므로Cross-Origin이다.
https://codestates.com:443vshttps://codestates.com⇒ https의 기본 포트는 443입니다. 따라서 도메인, 프로토콜, 포트가 모두 같은Same-Origin이다.
- Cross-Site : eTLD+1이 다른 경우
Cross-Site로 구분된다.
여기서 eTLD+1 이란,.com,.org과 같이 도메인의 가장 마지막 부분을 TLD(Top Level Domain, 최상위 도메인)라고 하는데, 이 최상위 도메인의 바로 왼쪽의 하위 레벨 도메인을 합한 것을 eTLD+1 이라고 한다.
참고로, 요즘 자주 볼 수 있는.io의 경우 바로 왼쪽의 주소를 하나 더 합한 것을 TLD라고 판단한다.
http://codestates.comvshttps://codestates.com⇒ 두 주소 모두 TLD는.com, eTLD+1은codestates.com으로 같으므로Same-Site이다.
https://code.github.iovshttps://states.github.io⇒ 두 주소 모두 TLD가github.io로 같지만, eTLD+1은 각각code.github.io,states.github.io로 다르므로Cross-Site이다.
SameSite 옵션에서 사용할 수 있는 속성은 다음과 같다.
Cross-Site 요청이라면 GET 메서드에 대해서만 쿠키를 전송할 수 있다.Cross-Site가 아닌 Same-Site인 경우에만 쿠키를 전송할 수 있다.Cross-Site에 대해 가장 관대한 옵션으로 항상 쿠키를 보내줄 수 있다.Secure 옵션이 필요하다.Set-Cookie라는 프로퍼티로 쿠키를 담아 전송한다.Cookie라는 프로퍼티에 쿠키를 담아 서버에 쿠키를 전송하게 된다.Stateless한 인터넷 연결을 Stateful하게 유지할 수 있다.HttpOnly 옵션을 사용하지 않았다면 자바스크립트를 이용해서 쿠키에 접근할 수 있기 때문에 쿠키에 민감한 정보를 담는 것은 위험하다.MDN - Set-Cookie Attributes

사용자가 웹사이트에서 아이디 및 비밀번호를 이용해서 로그인을 시도하면(그림 ①), 과연 어떤 일이 벌어질까?
➡ 사용자가 만일 정확한 아이디와 비밀번호를 입력했다면, 서버는 인증(Authentication)에 성공했다고 판단할 것이다.
그렇다면, 다음번에 인증을 필요로 하는 작업(e.g. 그림에서와 같이, 장바구니에 물품 추가)을 요청할 경우에 한번 더 로그인 과정을 거쳐야 할까?
➡ 아니다. 서버가 "해당 유저는 인증에 성공했음"을 알고 있다면, 유저가 매번 로그인할 필요가 없을 것이다.
여기서 몇 가지 용어가 등장한다.
사용자가 인증에 성공한 상태는 세션이라고 부른다.
세션이 만들어지면, 각 세션을 구분할 수 있는 세션 아이디도 만들어지는데(그림 ③),
보통 클라이언트에 세션 성공을 증명할 수단으로써 세션 아이디를 전달한다. (그림 ④)
그렇다면, 로그아웃은 어떻게 구현해야 할까?
세션 아이디가 담긴 쿠키는 클라이언트에 저장되어 있으며, 서버는 세션을 저장하고 있다.
그리고 서버는 그저 세션 아이디로만 인증 여부를 판단한다.
⚠ 주의 : 쿠키는 세션 아이디, 즉 인증 성공에 대한 증명을 갖고 있으므로, 탈취될 경우 서버는 해당 요청이 인증된 사용자의 요청이라고 판단한다. 이것이, 우리가 공공 PC에서 로그아웃해야 하는 이유이다.
그러므로 로그아웃은 다음 두 가지 작업을 해야 한다.
res.cookie로 쿠키의 값을 무효한 값으로 변경하거나, res.clearCookie로 쿠키를 삭제해 버리면 된다.express-session이라는 모듈이 존재한다.express-session은 세션을 위한 미들웨어로, express 서버에서 쉽게 세션을 위한 공간을 다룰 수 있도록 만들어준다.
const express = require('express');
const session = require('express-session');
const app = express();
app.use(
session({
secret: '@codestates',
resave: false,
saveUninitialized: true,
cookie: {
domain: 'localhost',
path: '/',
maxAge: 24 * 6 * 60 * 10000,
sameSite: 'none',
httpOnly: false,
secure: true,
},
})
);
express-session를 사용해 위와 같이 세션의 옵션을 지정할 수 있다.secret 옵션의 비밀키를 이용해 암호화해 세션 id라는 것을 생성한다.세션 id는 이에 종속되는 고유한 세션 객체를 가지며 이는 서버에 저장된다.세션 id를 이용해 유저의 인증여부를 판단할 수 있다.req.session으로 접근할 수 있으며 앞서 말했듯 이를 통해 세션에 임의의 데이터를 저장하거나 불러올 수 있다.| 설명 | 접속 상태 저장 경로 | 장점 | 단점 | |
|---|---|---|---|---|
| Cookie | 쿠키는 그저 http의 stateless한 것을 보완해주는 도구 | 클라이언트 | 서버에 부담을 덜어줌 | 쿠키 그 자체는 인증이 아님 |
| Session | 접속 상태를 서버가 가짐 (stateful) 접속 상태와 권한 부여를 위해 세션 아이디를 쿠키로 전송 | 서버 | 신뢰할 수 있는 유저인지 서버에서 추가로 확인 가능 | 하나의 서버에서만 접속 상태를 가지므로 분산에 불리 |