Cookie - g-market/b-shop-backend GitHub Wiki

Cookie

μΏ ν‚€λŠ” λΈŒλΌμš°μ €μ— μ €μž₯λ˜λŠ” μž‘μ€ 크기의 λ¬Έμžμ—΄λ‘œ HTTP ν”„λ‘œν† μ½œμ˜ μΌλΆ€μž…λ‹ˆλ‹€.

μΏ ν‚€λŠ” 주둜 μ›Ή μ„œλ²„μ— μ˜ν•΄ λ§Œλ“€μ–΄μ§‘λ‹ˆλ‹€.

μ„œλ²„κ°€ HTTP 응닡 헀더(header)의 Set-Cookie에 λ‚΄μš©μ„ λ„£μ–΄ μ „λ‹¬ν•˜λ©΄, λΈŒλΌμš°μ €λŠ” 이 λ‚΄μš©μ„ 자체적으둜 λΈŒλΌμš°μ €μ— μ €μž₯ν•©λ‹ˆλ‹€.

μΏ ν‚€λŠ” ν΄λΌμ΄μ–ΈνŠΈ 식별과 같은 인증에 κ°€μž₯ 많이 μ“°μž…λ‹ˆλ‹€.

  1. μ‚¬μš©μžκ°€ λ‘œκ·ΈμΈν•˜λ©΄ μ„œλ²„λŠ” HTTP 응닡 ν—€λ”μ˜ Set-Cookie에 λ‹΄κΈ΄ access token μž¬λ°œκΈ‰ μš©λ„ 정보λ₯Ό μ‚¬μš©ν•΄ μΏ ν‚€λ₯Ό μ„€μ •
  2. μ‚¬μš©μžκ°€ 동일 도메인에 μ ‘μ†ν•˜λ €κ³  ν•˜λ©΄ λΈŒλΌμš°μ €λŠ” HTTP Cookie 헀더에 Refresh Token을 ν•¨κ»˜ μ‹€μ–΄ μ„œλ²„μ— μš”μ²­μ„ λ³΄λƒ…λ‹ˆλ‹€.
  3. μ„œλ²„λŠ” λΈŒλΌμš°μ €κ°€ 보낸 μš”μ²­ ν—€λ”μ˜ Refresh Tokenλ₯Ό 읽어 μ‚¬μš©μžμ—κ²Œ access token을 μž¬λ°œκΈ‰ν•©λ‹ˆλ‹€.

Cookie Option

refreshToken=61da9252-c1f7-11ed-a50e-02f2f3f2da68;
Path=/;
Max-Age=1209600;
Expires=Mon, 27 Mar 2023 23:32:56 GMT;
Secure;
HttpOnly;
SameSite=None

path

path=/

URL path(경둜)의 μ ‘λ‘μ‚¬λ‘œ, 이 κ²½λ‘œλ‚˜ 이 경둜의 ν•˜μœ„ κ²½λ‘œμ— μžˆλŠ” νŽ˜μ΄μ§€λ§Œ 쿠킀에 μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ ˆλŒ€ κ²½λ‘œμ΄μ–΄μ•Ό ν•˜κ³ , (λ―Έ μ§€μ •μ‹œ) 기본값은 ν˜„μž¬ κ²½λ‘œμž…λ‹ˆλ‹€.

path=/admin μ˜΅μ…˜μ„ μ‚¬μš©ν•˜μ—¬ μ„€μ •ν•œ μΏ ν‚€λŠ” /adminκ³Ό /admin/something에선 λ³Ό 수 μžˆμ§€λ§Œ, /home μ΄λ‚˜ /adminpage에선 μΏ ν‚€λ₯Ό λ³Ό 수 μ—†μŠ΅λ‹ˆλ‹€.

νŠΉλ³„ν•œ κ²½μš°κ°€ μ•„λ‹ˆλΌλ©΄, path μ˜΅μ…˜μ„ path=/ 같이 루트둜 μ„€μ •ν•΄ μ›Ήμ‚¬μ΄νŠΈμ˜ λͺ¨λ“  νŽ˜μ΄μ§€μ—μ„œ 쿠킀에 μ ‘κ·Όν•  수 μžˆλ„λ‘ ν•©μ‹œλ‹€.

domain

domain=site.com

쿠킀에 μ ‘κ·Ό κ°€λŠ₯ν•œ domain(도메인)을 μ§€μ •ν•©λ‹ˆλ‹€. λ‹€λ§Œ, λͺ‡ κ°€μ§€ μ œμ•½μ΄ μžˆμ–΄μ„œ 아무 λ„λ©”μΈμ΄λ‚˜ μ§€μ •ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

domain μ˜΅μ…˜μ— 아무 값도 λ„£μ§€ μ•Šμ•˜λ‹€λ©΄, μΏ ν‚€λ₯Ό μ„€μ •ν•œ λ„λ©”μΈμ—μ„œλ§Œ 쿠킀에 μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€. site.comμ—μ„œ μ„€μ •ν•œ μΏ ν‚€λŠ” other.comμ—μ„œ 얻을 수 μ—†μ£ .

이 외에 κΉŒλ‹€λ‘œμš΄ μ œμ•½μ‚¬ν•­μ΄ ν•˜λ‚˜ 더 μžˆμŠ΅λ‹ˆλ‹€. μ„œλΈŒ 도메인(subdomain)인 sub.site.comμ—μ„œλ„ μΏ ν‚€ 정보λ₯Ό 얻을 수 μ—†λ‹€λŠ” μ μž…λ‹ˆλ‹€.

μ„œλΈŒ λ„λ©”μΈμ΄λ‚˜ λ‹€λ₯Έ λ„λ©”μΈμ—μ„œ 쿠킀에 접속할 방법은 μ—†μŠ΅λ‹ˆλ‹€. site.comμ—μ„œ μƒμ„±ν•œ μΏ ν‚€λ₯Ό other.com에선 μ ˆλŒ€ 전솑받을 수 μ—†μŠ΅λ‹ˆλ‹€.

그런데 정말 forum.site.comκ³Ό 같은 μ„œλΈŒ λ„λ©”μΈμ—μ„œ site.comμ—μ„œ μƒμ„±ν•œ μΏ ν‚€ 정보λ₯Ό 얻을 방법이 μ—†λŠ” κ±ΈκΉŒμš”?

방법이 μžˆμŠ΅λ‹ˆλ‹€. site.comμ—μ„œ μΏ ν‚€λ₯Ό μ„€μ •ν•  λ•Œ domain μ˜΅μ…˜μ— 루트 도메인인 domain=site.com을 λͺ…μ‹œμ μœΌλ‘œ μ„€μ •ν•΄ μ£Όλ©΄ 되죠.

expires와 max-age

Expires=Mon, 27 Mar 2023 23:32:56 GMT; Max-Age=1209600;

expires(유효 일자)λ‚˜ max-age(만료 κΈ°κ°„) μ˜΅μ…˜μ΄ μ§€μ •λ˜μ–΄μžˆμ§€ μ•ŠμœΌλ©΄, λΈŒλΌμš°μ €κ°€ λ‹«νž λ•Œ 쿠킀도 ν•¨κ»˜ μ‚­μ œλ©λ‹ˆλ‹€. 이런 μΏ ν‚€λ₯Ό "μ„Έμ…˜ μΏ ν‚€(session cookie)"라고 λΆ€λ¦…λ‹ˆλ‹€.

expires λ‚˜ max-age μ˜΅μ…˜μ„ μ„€μ •ν•˜λ©΄ λΈŒλΌμš°μ €λ₯Ό 닫아도 μΏ ν‚€κ°€ μ‚­μ œλ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λΈŒλΌμš°μ €λŠ” μ„€μ •λœ 유효 μΌμžκΉŒμ§€ μΏ ν‚€λ₯Ό μœ μ§€ν•˜λ‹€κ°€, ν•΄λ‹Ή μΌμžκ°€ λ„λ‹¬ν•˜λ©΄ μΏ ν‚€λ₯Ό μžλ™μœΌλ‘œ μ‚­μ œν•©λ‹ˆλ‹€.

μΏ ν‚€μ˜ 유효 μΌμžλŠ” λ°˜λ“œμ‹œ GMT(Greenwich Mean Time) 포맷으둜 μ„€μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.

secure

secure

이 μ˜΅μ…˜μ„ μ„€μ •ν•˜λ©΄ HTTPS둜 ν†΅μ‹ ν•˜λŠ” κ²½μš°μ—λ§Œ μΏ ν‚€κ°€ μ „μ†‘λ©λ‹ˆλ‹€.

secure μ˜΅μ…˜μ΄ μ—†μœΌλ©΄ κΈ°λ³Έ 섀정이 μ μš©λ˜μ–΄ http://site.com μ—μ„œ μ„€μ •(생성)ν•œ μΏ ν‚€λ₯Ό https://site.com μ—μ„œ 읽을 수 있고, https://site.com μ—μ„œ μ„€μ •(생성)ν•œ 쿠킀도 http://site.com μ—μ„œ 읽을 수 μžˆμŠ΅λ‹ˆλ‹€.

μΏ ν‚€λŠ” 기본적으둜 λ„λ©”μΈλ§Œ ν™•μΈν•˜μ§€ ν”„λ‘œν† μ½œμ„ λ”°μ§€μ§„ μ•ŠκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

ν•˜μ§€λ§Œ secure μ˜΅μ…˜μ΄ μ„€μ •λœ 경우, https://site.com μ—μ„œ μ„€μ •ν•œ μΏ ν‚€λŠ” http://site.com μ—μ„œ μ ‘κ·Όν•  수 μ—†μŠ΅λ‹ˆλ‹€. 쿠킀에 λ―Όκ°ν•œ λ‚΄μš©μ΄ μ €μž₯λ˜μ–΄ μžˆμ–΄ μ•”ν˜Έν™”λ˜μ§€ μ•Šμ€ HTTP 연결을 톡해 μ „λ‹¬λ˜λŠ” κ±Έ μ›μΉ˜ μ•ŠλŠ”λ‹€λ©΄ 이 μ˜΅μ…˜μ„ μ‚¬μš©ν•˜λ©΄ λ©λ‹ˆλ‹€.

samesite

SameSite=None

또 λ‹€λ₯Έ λ³΄μ•ˆ 속성인 samesite μ˜΅μ…˜μ€ 크둜슀 μ‚¬μ΄νŠΈ μš”μ²­ μœ„μ‘°(cross-site request forgery, XSRF) 곡격을 막기 μœ„ν•΄ λ§Œλ“€μ–΄μ§„ μ˜΅μ…˜μž…λ‹ˆλ‹€.

XSRF 곡격

ν˜„μž¬ John이 bank.com에 λ‘œκ·ΈμΈλ˜μ–΄μžˆλ‹€κ³  κ°€μ •ν•΄ λ΄…μ‹œλ‹€. ν•΄λ‹Ή μ‚¬μ΄νŠΈμ—μ„œ μ‚¬μš©λ˜λŠ” 인증 μΏ ν‚€κ°€ λΈŒλΌμš°μ €μ— μ €μž₯되고, λΈŒλΌμš°μ €λŠ” bank.com에 μš”μ²­μ„ 보낼 λ•Œλ§ˆλ‹€ 인증 μΏ ν‚€λ₯Ό ν•¨κ»˜ 전솑할 κ²ƒμž…λ‹ˆλ‹€. μ„œλ²„λŠ” 전솑받은 μΏ ν‚€λ₯Ό μ΄μš©ν•΄ μ‚¬μš©μžλ₯Ό μ‹λ³„ν•˜κ³ , λ³΄μ•ˆμ΄ ν•„μš”ν•œ μž¬μ • 거래λ₯Ό μ²˜λ¦¬ν•©λ‹ˆλ‹€.

이제 (λ‘œκ·Έμ•„μ›ƒν•˜μ§€ μ•Šκ³ ) λ‹€λ₯Έ 창을 λ„μ›Œμ„œ μ›Ή μ„œν•‘μ„ ν•˜λ˜ 도쀑에 λœ»ν•˜μ§€ μ•Šκ²Œ aliceκ°€ bob.com에 μ ‘μ†ν–ˆλ‹€ κ°€μ •ν•΄ λ΄…μ‹œλ‹€. 이 μ‚¬μ΄νŠΈμ—” bobμ—κ²Œ μ†‘κΈˆμ„ μš”μ²­ν•˜λŠ” 폼(form) <form action="https://bank.com/pay">" 이 있고, 이 폼은 μžλ™μœΌλ‘œ μ œμΆœλ˜λ„λ‘ μ„€μ •λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

폼이 bob.comμ—μ„œ 은행 μ‚¬μ΄νŠΈλ‘œ λ°”λ‘œ 전솑될 λ•Œ 인증 쿠킀도 ν•¨κ»˜ μ „μ†‘λ©λ‹ˆλ‹€. bank.com에 μš”μ²­μ„ 보낼 λ•Œλ§ˆλ‹€ bank.comμ—μ„œ μ„€μ •ν•œ μΏ ν‚€κ°€ μ „μ†‘λ˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. 은행은 전솑받은 μΏ ν‚€λ₯Ό 읽어 (해컀가 μ•„λ‹Œ) 계정 주인이 μ ‘μ†ν•œ 것이라 μƒκ°ν•˜κ³  ν•΄μ»€μ—κ²Œ λˆμ„ μ†‘κΈˆν•©λ‹ˆλ‹€.

img_1

이런 곡격을 크둜슀 μ‚¬μ΄νŠΈ μš”μ²­ μœ„μ‘°λΌκ³  λΆ€λ¦…λ‹ˆλ‹€.

μ‹€μ œ 은행은 λ‹Ήμ—°νžˆ 이 곡격을 막을 수 μžˆλ„λ‘ μ‹œμŠ€ν…œμ„ μ„€κ³„ν•©λ‹ˆλ‹€. bank.comμ—μ„œ μ‚¬μš©ν•˜λŠ” λͺ¨λ“  폼에 "XSRF 보호 토큰(protection token)"μ΄λΌλŠ” 특수 ν•„λ“œλ₯Ό λ„£μ–΄μ„œ 말이죠. 이 토큰은 μ•…μ˜μ μΈ νŽ˜μ΄μ§€μ—μ„œ λ§Œλ“€ 수 μ—†κ³ , 원격 νŽ˜μ΄μ§€μ—μ„œλ„ 훔쳐 올 수 없도둝 κ΅¬ν˜„λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ μ•…μ˜μ μΈ νŽ˜μ΄μ§€μ—μ„œ 폼을 μ „μ†‘ν•˜λ”λΌλ„ 보호 토큰이 μ—†κ±°λ‚˜ μ„œλ²„μ— μ €μž₯된 κ°’κ³Ό μΌμΉ˜ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μš”μ²­μ΄ λ¬΄μš©μ§€λ¬Όμ΄ λ©λ‹ˆλ‹€.

ν•˜μ§€λ§Œ 이런 μ ˆμ°¨λŠ” κ΅¬ν˜„μ— μ‹œκ°„μ΄ κ±Έλ¦°λ‹€λŠ” 단점을 μˆ˜λ°˜ν•©λ‹ˆλ‹€. λͺ¨λ“  폼에 보호 토큰을 μ„ΈνŒ…ν•΄μ€˜μ•Ό ν•˜μ£ . λ˜ν•œ μš”μ²­ μ „λΆ€λ₯Ό κ²€μˆ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€.

httpOnly

httpOnly μ˜΅μ…˜μ€ μ›Ήμ„œλ²„μ—μ„œ Set-Cookie 헀더λ₯Ό μ΄μš©ν•΄ μΏ ν‚€λ₯Ό μ„€μ •ν•  λ•Œ μ§€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

이 μ˜΅μ…˜μ€ μžλ°”μŠ€ν¬λ¦½νŠΈ 같은 ν΄λΌμ΄μ–ΈνŠΈ μΈ‘ μŠ€ν¬λ¦½νŠΈκ°€ μΏ ν‚€λ₯Ό μ‚¬μš©ν•  수 μ—†κ²Œ ν•©λ‹ˆλ‹€. document.cookieλ₯Ό 톡해 μΏ ν‚€λ₯Ό λ³Ό μˆ˜λ„ μ—†κ³  μ‘°μž‘ν•  μˆ˜λ„ μ—†μŠ΅λ‹ˆλ‹€.

해컀가 μ•…μ˜μ μΈ μžλ°”μŠ€ν¬λ¦½νŠΈ μ½”λ“œλ₯Ό νŽ˜μ΄μ§€μ— μ‚½μž…ν•˜κ³  μ‚¬μš©μžκ°€ κ·Έ νŽ˜μ΄μ§€μ— μ ‘μ†ν•˜κΈ°λ₯Ό κΈ°λ‹€λ¦¬λŠ” λ°©μ‹μ˜ 곡격을 μ˜ˆλ°©ν•  λ•Œ 이 μ˜΅μ…˜μ„ μ‚¬μš©ν•©λ‹ˆλ‹€. μš°λ¦¬κ°€ λ§Œλ“  μ‚¬μ΄νŠΈμ— 해컀가 μ•…μ˜μ μΈ μ½”λ“œλ₯Ό μ‚½μž…ν•˜μ§€ λͺ»ν•˜λ„둝 μ˜ˆλ°©ν•΄μ•Ό ν•˜μ§€λ§Œ, 버그가 μžˆμ„ ν™•λ₯ μ€ μ–Έμ œλ‚˜ 있기 λ•Œλ¬Έμ— 해컀가 μ½”λ“œλ₯Ό μ‚½μž…ν•  κ°€λŠ₯성이 μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

이런 상황이 λ§Œμ— ν•˜λ‚˜ λ°œμƒν•˜λ©΄, μ‚¬μš©μžκ°€ μ›Ή νŽ˜μ΄μ§€μ— λ°©λ¬Έν•  λ•Œ document.cookieλ₯Ό λ³Ό 수 있고 μ‘°μž‘λ„ ν•  수 μžˆλŠ” ν•΄μ»€μ˜ μ½”λ“œλ„ ν•¨κ»˜ μ‹€ν–‰λ©λ‹ˆλ‹€. λ¬Όλ‘  μΏ ν‚€μ—” 인증 정보가 μžˆμ–΄μ„œ 해컀가 이 정보λ₯Ό ν›”μΉ˜κ±°λ‚˜ μ‘°μž‘ν•  수 있게 λ©λ‹ˆλ‹€. μ’‹μ§€ μ•Šμ€ 상황이 λ°œμƒν•˜μ£ .

ν•˜μ§€λ§Œ httpOnly μ˜΅μ…˜μ΄ μ„€μ •λœ μΏ ν‚€λŠ” document.cookie둜 μΏ ν‚€ 정보λ₯Ό 읽을 수 μ—†κΈ° λ•Œλ¬Έμ— μΏ ν‚€λ₯Ό λ³΄ν˜Έν•  수 μžˆμŠ΅λ‹ˆλ‹€.