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 요청 전에 토큰이 만료됐다면 바로 재발급 요청을 할 수도 있다.
참고