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.com
vshttps://codestates.com
⇒ 프로토콜이 다르므로Cross-Origin
이다.
https://codestates.com:443
vshttps://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.com
vshttps://codestates.com
⇒ 두 주소 모두 TLD는.com
, eTLD+1은codestates.com
으로 같으므로Same-Site
이다.
https://code.github.io
vshttps://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) 접속 상태와 권한 부여를 위해 세션 아이디를 쿠키로 전송 | 서버 | 신뢰할 수 있는 유저인지 서버에서 추가로 확인 가능 | 하나의 서버에서만 접속 상태를 가지므로 분산에 불리 |