Today I Learned
- Cookie
- Session
- Token
서버가 어떤 데이터를 브라우저 측에 저장한 후 다시 그 데이터를 받아오는 기술, 또는 그 데이터 자체
해당 도메인에 대해 쿠키가 존재하면 웹 브라우저는 http 요청 시, 서버에 쿠키를 함께 전달한다. 이러한 쿠키를 활용하면, HTTP 프로토콜은 상태가 없는(stateless) 특성을 가지고 있음에도 정보를 유지할 수 있다.
서버가 브라우저로 쿠키를 보내는 것은 일회성 작업이지만, 브라우저가 서버로 쿠키를 돌려 보내는 것은 일정 시간동안 반복해서 수행하는 작업이다. 즉, 서버에서는 쿠키를 한번 보내서 브라우저에 저장해두면, 브라우저가 일정 기간동안 알아서 쿠키를 서버로 보내주는 것이다.
클라이언트 서버 모델에서는 서버가 클라이언트의 요청없이 클라이언트로 데이터를 보낼 수 없다. 따라서 쿠키 전달 과정은 서버가 클라이언트 요청에 응답할 때 일어난다. http 응답 시, 서버는 Set-Cookie라는 응답 헤더에 브라우저가 수신해야 할 쿠키 정보를 명시한다.
http 응답 헤더의 쿠키 옵션
'Set-Cookie':[
'이름1=값1',
'이름2=값2; Secure',
'이름3=값3; HttpOnly',
'이름4=값4; Path=/cookie',
'이름5=값4; Domain=google.com'
]
'Set-Cookie':[
'cookie=iamcookie',
'Secure=Secure; Secure',
'HttpOnly=HttpOnly; HttpOnly',
'Path=Path; Path=/cookie',
'Doamin=Domain; Domain=google.com'
]
http 요청 헤더의 쿠키 옵션
Cookie라는 요청 헤더에 실어서 돌려 보낸다.쿠키 옵션에서 도메인은 포트 및 서브 도메인 정보, 세부 경로를 포함하지 않는다. 예를 들어 요청해야 할 URL가 https://www.google.com/users/login 이라면 Domain은 google.com이 된다. 이를 통해 google.com이 아닌 도메인에 쿠키를 전송하는 일을 막을 수 있다.
URL의 세부 경로로, 요청해야 할 URL가 https://www.google.com/users/login 이라면 Path는 /users/login이 된다. Path는 설정된 경로를 포함하는 하위 경로로 요청을 하더라도 쿠키를 서버에 전송할 수 있다. 예를 들어, Path가 /users로 설정돼있으면 /users/signup 경로로 쿠키를 전송할 수 있다.
따로 명시하지 않는 경우, Path의 기본 값은 /이다.
쿠키가 유효한 기간을 정하는 옵션이다. 유효기간을 설정하는 것이 보안상 유리하다.
MaxAge : 쿠키가 유효한 시간을 초 단위로 설정Expires : 언제까지 쿠키가 유효한지 설정위 옵션의 여부에 따라 쿠키는 세션 쿠키(Session Cookie)와 영속성 쿠키(Persistent Cookie)로 나눠진다.
세션 쿠키(Session Cookie) : MaxAge 또는 Expires 옵션이 없는 쿠키로, 브라우저를 종료하면 해당 쿠키는 삭제됨영속성 쿠키(Persistent Cookie) : 브라우저의 종료 여부와 상관없이 MaxAge 또는 Expires에 지정된 유효시간만큼 사용가능함사용하는 프로토콜에 따른 쿠키의 전송 여부를 결정하는 옵션이다.
Secure을 명시한 경우 : https를 이용하는 경우에만 쿠키 전송 가능Secure을 명시하지 않은 경우 : http, https 모두에 쿠키 전송 가능단, Secure 옵션을 명시했지만 도메인이 localhost인 경우에는 https가 아니여도 쿠키 전송이 가능하다.
자바스크립트로 브라우저의 쿠키에 접근이 가능한지 여부를 결정하는 옵션이다.
httpOnly을 명시한 경우 : 브라우저에서 자바스크립트로 쿠키에 접근할 수 없음httpOnly을 명시하지 않은 경우 : 자바스크립트로 Document.cookie 객체를 통해 쿠키에 접근할 수 있어 쿠키 탈취의 위험이 있음Cross-Origin(CORS) 요청을 받은 경우, 요청에서 사용한 메소드와 해당 옵션의 조합을 기준으로 서버의 쿠키 전송 여부를 결정한다.
Cross-Origin : 도메인, 프로토콜, 포트 중 하나라도 다른 경우
Lax : Cross-Origin 요청이라면 GET 메소드에 대해서만 쿠키를 전송 가능Strict : Cross-Origin이 아닌 same-site 인 경우에만 쿠키를 전송 가능None : Cross-Origin이더라도 항상 쿠키 전송 가능하나, 대신 Secure 옵션이 필요함
로그아웃
클라이언트에서 세션 정보를 없애기 위해서는 res.cookie로 쿠키의 값을 무효한 값으로 갱신하거나, res.clearCookie로 쿠키를 삭제하면 된다.
세션을 위한 미들웨어로, express 서버에서 쉽게 세션을 위한 공간을 다룰 수 있도록 만들어준다. secret 옵션의 비밀키를 이용해 암호화해 세션 id를 생성해 쿠키에 담아 클라이언트로 전송한다.
const express = require('express');
const session = require('express-session');
const app = express();
app.use(
session({
secret: '@secretKey',
resave: false,
saveUninitialized: true,
cookie: {
domain: 'localhost',
path: '/',
maxAge: 24 * 6 * 60 * 10000,
sameSite: 'none',
httpOnly: false,
secure: true,
},
})
);
가장 많이 쓰이는 암호화 방식중에 하나로, 복호화가 가능한 다른 암호화 방식들과 달리 해싱은 암호화만 가능하다. 해싱의 목적은 데이터 그 자체를 사용하는 것이 아니라, 동일한 값의 데이터를 사용하고 있는지 여부만 확인하는 것이 목적이기 때문이다. (단방향 암호화 방식)
( 이미지 출처: https://ko.wikipedia.org/wiki/%EB%A0%88%EC%9D%B8%EB%B3%B4_%ED%85%8C%EC%9D%B4%EB%B8%94 )
해시 함수를 사용해 변환 가능한 모든 해시 값을 저장시켜 놓은 표로, 해시 함수를 거치기 이전의 값을 알아내는 데에 사용된다. 유출 될 경우, 보안의 위협이 될 수 있다. 이를 대비해 솔트를 활용한다.
( 이미지 출처: https://ko.wikipedia.org/wiki/%EC%86%94%ED%8A%B8_(%EC%95%94%ED%98%B8%ED%95%99 )
해싱 이전 값에 임의의 값을 더해 데이터가 유출되더라도 해싱 이전의 값을 알아내기 더욱 어렵게 만드는 방법이다. 해싱 대상 값에 대해 복잡도를 높이거나, 같은 입력 값에 대해 다른 해시 값을 줄 수 있다.
JSON 객체에 정보를 담고 이를 토큰으로 암호화하여 전송할 수 있는 기술

( 이미지 출처 : https://millo-l.github.io/JWT-%EA%B8%B0%EB%B0%98-%EC%9D%B8%EC%A6%9D%EB%B0%A9%EC%8B%9D/ )
1. Header
토큰의 타입과 해시 암호화 알고리즘을 JSON 형태로 작성한다.
2. Payload
전달하려는 내용물을 담고 있는 부분으로, 마찬가지로 JSON 형태로 작성한다.
3. Signature
토큰의 무결성을 확인할 수 있는 부분으로, 시크릿키와 Header의 알고리즘을 사용해 해싱한다.
Access Token
서버에 접근하기 위한 토큰으로, 일반적으로 암호화된 인증 정보를 담고있다. 보안을 위해 보통 24시간 정도의 짧은 유효기간이 설정된다.
Refresh Token
서버 접근을 위한 토큰이 아닌 액세스 토큰이 만료되었을 때 새로운 액세스 토큰을 발급받기 위해 사용되는 토큰이다. 그렇기 때문에 Access Token보다 유효기간이 길게 설정된다.


Access Token 만료가 될 때마다 계속 과정 9~11을 거칠 필요는 없다.
클라이언트에서 Access Token의 Payload를 통해 유효기간을 알 수 있기 때문에 프론트엔드 단에서 API 요청 전에 토큰이 만료됐다면 바로 재발급 요청을 할 수도 있다.
참고