[Network] CORS

GreenBeanΒ·2021λ…„ 10μ›” 5일
0
post-thumbnail

CORS

CORSλž€?

  • CORSλŠ” Cross-Origin Resource Sharing의 μ•½μž
  • ꡐ차 좜처 λ¦¬μ†ŒμŠ€ 곡유둜 λ²ˆμ—­λ  수 μžˆλŠ”λ°, λΈŒλΌμš°μ €μ—μ„œ λ‹€λ₯Έ 좜처의 λ¦¬μ†ŒμŠ€λ₯Ό κ³΅μœ ν•˜λŠ” 방법

좜처(origin)μ΄λž€?

  • μΆœμ²˜λŠ” Protocolκ³Ό Host, Portλ₯Ό λͺ¨λ‘ ν•©μΉœ 것을 의미
    • 즉, μ„œλ²„μ˜ μœ„μΉ˜λ₯Ό μ°Ύμ•„κ°€κΈ° μœ„ν•΄ ν•„μš”ν•œ κ°€μž₯ 기본적인 것듀을 합쳐놓은 것
    • 좜처 λ‚΄μ˜ 포트 λ²ˆν˜ΈλŠ” μƒλž΅μ΄ κ°€λŠ₯ν•œλ°, μ΄λŠ” 각 μ›Ήμ—μ„œ μ‚¬μš©ν•˜λŠ” HTTP, HTTPS ν”„λ‘œν† μ½œμ˜ κΈ°λ³Έ 포트 λ²ˆν˜Έκ°€ μ •ν•΄μ ΈμžˆκΈ° λ•Œλ¬Έ
      • κ·ΈλŸ¬λ‚˜ λ§Œμ•½ https://google.com:443κ³Ό 같이 μΆœμ²˜μ— 포트 λ²ˆν˜Έκ°€ λͺ…μ‹œμ μœΌλ‘œ ν¬ν•¨λ˜μ–΄ μžˆλ‹€λ©΄ 이 포트 λ²ˆν˜ΈκΉŒμ§€ λͺ¨λ‘ μΌμΉ˜ν•΄μ•Ό 같은 좜처라고 인정
      • ν•˜μ§€λ§Œ 이 μΌ€μ΄μŠ€μ— λŒ€ν•œ λͺ…ν™•ν•œ μ •μ˜κ°€ ν‘œμ€€μœΌλ‘œ 정해진 것은 μ•„λ‹ˆκΈ° λ•Œλ¬Έμ—, 더 μ •ν™•νžˆ μ΄μ•ΌκΈ°ν•˜μžλ©΄ μ–΄λ–€ κ²½μš°μ—λŠ” 같은 좜처, 또 μ–΄λ–€ κ²½μš°μ—λŠ” λ‹€λ₯Έ 좜처둜 νŒλ‹¨λ  μˆ˜λ„ 있음
  • λΈŒλΌμš°μ €μ˜ 개발자 λ„κ΅¬μ˜ μ½˜μ†”μ—μ„œ 객체가 가지고 μžˆλŠ” origin ν”„λ‘œνΌν‹°μ— μ ‘κ·Όν•¨μœΌλ‘œμ¨ μ‹€ν–‰λ˜κ³  μžˆλŠ” 좜처λ₯Ό μ•Œμ•„λ‚Ό 수 있음

같은 좜처 vs λ‹€λ₯Έ 좜처

  • ν˜„μž¬ μ›ΉνŽ˜μ΄μ§€μ˜ μ£Όμ†Œκ°€ https://velog.io/@hwaya2828일 λ•Œ

    URL결과이유
    https://velog.io/@hwaya2828/about같은 좜처Protocal, Host, Port 동일
    https://velog.io/@hwaya2828/about?q=network같은 좜처Protocal, Host, Port 동일
    https://velog.io/@hwaya2828/about#network같은 좜처Protocal, Host, Port 동일
    http://velog.io/@hwaya2828λ‹€λ₯Έ 좜처Protocal 닀름
    http://github.ioλ‹€λ₯Έ 좜처Host 닀름
    https://velog.io/@hwaya2828:8000?λΈŒλΌμš°μ €μ— 따라 닀름
  • λ§Œμ•½ μΆœμ²˜μ— https://velog.io/@hwaya2828:80처럼 포트 λ²ˆν˜Έκ°€ λͺ…μ‹œλ˜μ–΄ μžˆλ‹€λ©΄ λͺ…λ°±ν•˜κ²Œ λ‹€λ₯Έ 좜처둜 μΈμ •λ˜λŠ” λΆ€λΆ„μ΄μ§€λ§Œ, μ˜ˆμ‹œλ‘œ λ“  좜처의 경우 포트 λ²ˆν˜Έκ°€ ν¬ν•¨λ˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— νŒλ‹¨ν•˜κΈ°κ°€ 애맀
    • 이런 κ²½μš°μ—λŠ” 각 λΈŒλΌμš°μ €λ“€μ˜ λ…μžμ μΈ 좜처 비ꡐ λ‘œμ§μ„ λ”°λΌκ°€κ²Œ 됨
  • μ—¬κΈ°μ„œ μ€‘μš”ν•œ 사싀 ν•œ κ°€μ§€λŠ” 좜처λ₯Ό λΉ„κ΅ν•˜λŠ” 둜직이 μ„œλ²„μ— κ΅¬ν˜„λœ μŠ€νŽ™μ΄ μ•„λ‹ˆλΌ λΈŒλΌμš°μ €μ— κ΅¬ν˜„λ˜μ–΄ μžˆλŠ” μŠ€νŽ™μ΄λΌλŠ” 것
    • λ§Œμ•½ μš°λ¦¬κ°€ CORS 정책을 μœ„λ°˜ν•˜λŠ” λ¦¬μ†ŒμŠ€ μš”μ²­μ„ ν•˜λ”λΌλ„ ν•΄λ‹Ή μ„œλ²„κ°€ 같은 μΆœμ²˜μ—μ„œ 보낸 μš”μ²­λ§Œ λ°›κ² λ‹€λŠ” λ‘œμ§μ„ 가지고 μžˆλŠ” κ²½μš°κ°€ μ•„λ‹ˆλΌλ©΄ μ„œλ²„λŠ” μ •μƒμ μœΌλ‘œ 응닡을 ν•˜κ³ , 이후 λΈŒλΌμš°μ €κ°€ 이 응닡을 λΆ„μ„ν•΄μ„œ CORS μ •μ±… μœ„λ°˜μ΄λΌκ³  νŒλ‹¨λ˜λ©΄ κ·Έ 응닡을 μ‚¬μš©ν•˜μ§€ μ•Šκ³  κ·Έλƒ₯ λ²„λ¦¬λŠ” μˆœμ„œμΈ 것
  • 즉, CORSλŠ” λΈŒλΌμš°μ €μ˜ κ΅¬ν˜„ μŠ€νŽ™μ— ν¬ν•¨λ˜λŠ” 정책이기 λ•Œλ¬Έμ— λΈŒλΌμš°μ €λ₯Ό ν†΅ν•˜μ§€ μ•Šκ³  μ„œλ²„ κ°„ 톡신을 ν•  λ•ŒλŠ” 이 정책이 μ μš©λ˜μ§€ μ•ŠμŒ
  • λ˜ν•œ CORS 정책을 μœ„λ°˜ν•˜λŠ” λ¦¬μ†ŒμŠ€ μš”μ²­ λ•Œλ¬Έμ— μ—λŸ¬κ°€ λ°œμƒν–ˆλ‹€κ³  해도 μ„œλ²„ μͺ½ λ‘œκ·Έμ—λŠ” μ •μƒμ μœΌλ‘œ 응닡을 ν–ˆλ‹€λŠ” 둜그만 남기 λ•Œλ¬Έμ—, CORSκ°€ λŒμ•„κ°€λŠ” 방식을 μ •ν™•νžˆ λͺ¨λ₯΄λ©΄ μ—λŸ¬ νŠΈλ ˆμ΄μ‹±μ— λ‚œν•­μ„ κ²ͺ을 μˆ˜λ„ 있음

SOPλž€?

  • μ›Ήμ—μ„œλŠ” λ‹€λ₯Έ 좜처둜의 λ¦¬μ†ŒμŠ€ μš”μ²­μ„ μ œν•œν•˜λŠ” 것과 κ΄€λ ¨λœ 두 가지 정책이 쑴재
  • ν•œ κ°€μ§€λŠ” CORS, 그리고 또 ν•œ κ°€μ§€λŠ” SOP(Same-Origin Policy)
  • SOPλŠ” 2011λ…„, RFC 6454μ—μ„œ 처음 λ“±μž₯ν•œ λ³΄μ•ˆ μ •μ±…μœΌλ‘œ 말 κ·ΈλŒ€λ‘œ β€œκ°™μ€ μΆœμ²˜μ—μ„œλ§Œ λ¦¬μ†ŒμŠ€λ₯Ό κ³΅μœ ν•  수 μžˆλ‹€β€λΌλŠ” κ·œμΉ™μ„ 가진 μ •μ±…
  • κ·ΈλŸ¬λ‚˜ μ›Ήμ΄λΌλŠ” μ˜€ν”ˆμŠ€νŽ˜μ΄μŠ€ ν™˜κ²½μ—μ„œ λ‹€λ₯Έ μΆœμ²˜μ— μžˆλŠ” λ¦¬μ†ŒμŠ€λ₯Ό κ°€μ Έμ™€μ„œ μ‚¬μš©ν•˜λŠ” 일은 ꡉμž₯히 ν”ν•œ 일이라 λ¬΄μž‘μ • 막을 μˆ˜λ„ μ—†λŠ” λ…Έλ¦‡μ΄λ‹ˆ λͺ‡ 가지 μ˜ˆμ™Έ 쑰항을 두고 이 쑰항에 ν•΄λ‹Ήν•˜λŠ” λ¦¬μ†ŒμŠ€ μš”μ²­μ€ μΆœμ²˜κ°€ λ‹€λ₯΄λ”라도 ν—ˆμš©ν•˜κΈ°λ‘œ ν–ˆλŠ”λ°, κ·Έ 쀑 ν•˜λ‚˜κ°€ β€œCORS 정책을 지킨 λ¦¬μ†ŒμŠ€ μš”μ²­β€
    • CORSλΌλŠ” 이름이 처음 λ“±μž₯ν•œ 것은 2009년이라, SOP의 λ“±μž₯보닀 빠름
  • λ‹€λ₯Έ 좜처둜 λ¦¬μ†ŒμŠ€λ₯Ό μš”μ²­ν•œλ‹€λ©΄ SOP 정책을 μœ„λ°˜ν•œ 것이 되고, κ±°κΈ°λ‹€κ°€ SOP의 μ˜ˆμ™Έ 쑰항인 CORS μ •μ±…κΉŒμ§€ 지킀지 μ•ŠλŠ”λ‹€λ©΄ μ•„μ˜ˆ λ‹€λ₯Έ 좜처의 λ¦¬μ†ŒμŠ€λ₯Ό μ‚¬μš©ν•  수 μ—†κ²Œ λ˜λŠ” 것
  • 즉, μ΄λ ‡κ²Œ λ‹€λ₯Έ 좜처의 λ¦¬μ†ŒμŠ€λ₯Ό μ‚¬μš©ν•˜λŠ” 것을 μ œν•œν•˜λŠ” ν–‰μœ„λŠ” ν•˜λ‚˜μ˜ μ •μ±…λ§ŒμœΌλ‘œ κ²°μ •λœ 사항이 μ•„λ‹ˆλΌλŠ” 의미
    • SOPμ—μ„œ μ •μ˜λœ μ˜ˆμ™Έ μ‘°ν•­κ³Ό CORSλ₯Ό μ‚¬μš©ν•  수 μžˆλŠ” μΌ€μ΄μŠ€λ“€μ΄ λ§žλ¬Όλ¦¬μ§€ μ•Šμ„ κ²½μš°μ—λŠ” μ•„μ˜ˆ λ¦¬μ†ŒμŠ€ μš”μ²­μ„ ν•  수 μ—†λŠ” μΌ€μ΄μŠ€λ„ μ‘΄μž¬ν•  수 있음

SOP μ •μ±…μ˜ μž₯점

  • 동일 좜처 정책을 지킀면 μ™ΈλΆ€ λ¦¬μ†ŒμŠ€λ₯Ό κ°€μ Έμ˜€μ§€ λͺ»ν•΄ λΆˆνŽΈν•˜μ§€λ§Œ, 동일 좜처 정책은 XSSλ‚˜ XSRF λ“±μ˜ λ³΄μ•ˆ 취약점을 λ…Έλ¦° 곡격을 λ°©μ–΄ν•  수 있음

Tip! XSSλž€?

  • μ‚¬μ΄νŠΈ κ°„ μŠ€ν¬λ¦½νŒ…(cross-site scripting, XSS)은 μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ 많이 λ‚˜νƒ€λ‚˜λŠ” μ·¨μ•½μ μ˜ ν•˜λ‚˜λ‘œ μ›Ήμ‚¬μ΄νŠΈ κ΄€λ¦¬μžκ°€ μ•„λ‹Œ 이가 μ›Ή νŽ˜μ΄μ§€μ— μ•…μ„± 슀크립트λ₯Ό μ‚½μž…ν•  수 μžˆλŠ” 취약점
    • 주둜 μ—¬λŸ¬ μ‚¬μš©μžκ°€ 보게 λ˜λŠ” μ „μž κ²Œμ‹œνŒμ— μ•…μ„± μŠ€ν¬λ¦½νŠΈκ°€ λ‹΄κΈ΄ 글을 μ˜¬λ¦¬λŠ” ν˜•νƒœλ‘œ 이루어짐
  • 이 취약점은 μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ‚¬μš©μžλ‘œλΆ€ν„° μž…λ ₯ 받은 값을 μ œλŒ€λ‘œ κ²€μ‚¬ν•˜μ§€ μ•Šκ³  μ‚¬μš©ν•  경우 λ‚˜νƒ€λ‚¨
  • 이 μ·¨μ•½μ μœΌλ‘œ 해컀가 μ‚¬μš©μžμ˜ 정보(μΏ ν‚€, μ„Έμ…˜ λ“±)λ₯Ό νƒˆμ·¨ν•˜κ±°λ‚˜, μžλ™μœΌλ‘œ 비정상적인 κΈ°λŠ₯을 μˆ˜ν–‰ν•˜κ²Œ ν•  수 있음
  • 주둜 λ‹€λ₯Έ μ›Ήμ‚¬μ΄νŠΈμ™€ 정보λ₯Ό κ΅ν™˜ν•˜λŠ” μ‹μœΌλ‘œ μž‘λ™ν•˜λ―€λ‘œ μ‚¬μ΄νŠΈ κ°„ μŠ€ν¬λ¦½νŒ…μ΄λΌκ³  함

Tip! XSRFλž€?

  • μ‚¬μ΄νŠΈ κ°„ μš”μ²­ μœ„μ‘°(Cross-site request forgery, CSRF, XSRF)λŠ” μ›Ήμ‚¬μ΄νŠΈ 취약점 곡격의 ν•˜λ‚˜λ‘œ, μ‚¬μš©μžκ°€ μžμ‹ μ˜ μ˜μ§€μ™€λŠ” λ¬΄κ΄€ν•˜κ²Œ κ³΅κ²©μžκ°€ μ˜λ„ν•œ ν–‰μœ„(μˆ˜μ •, μ‚­μ œ, 등둝 λ“±)λ₯Ό νŠΉμ • μ›Ήμ‚¬μ΄νŠΈμ— μš”μ²­ν•˜κ²Œ ν•˜λŠ” 곡격을 말함
    • 유λͺ… 경맀 μ‚¬μ΄νŠΈμΈ μ˜₯μ…˜μ—μ„œ λ°œμƒν•œ κ°œμΈμ •λ³΄ 유좜 μ‚¬κ±΄μ—μ„œ μ‚¬μš©λœ 곡격 방식 쀑 ν•˜λ‚˜
  • μ‚¬μ΄νŠΈ κ°„ μŠ€ν¬λ¦½νŒ…(XSS)을 μ΄μš©ν•œ 곡격이 μ‚¬μš©μžκ°€ νŠΉμ • μ›Ήμ‚¬μ΄νŠΈλ₯Ό μ‹ μš©ν•˜λŠ” 점을 λ…Έλ¦° 것이라면, μ‚¬μ΄νŠΈκ°„ μš”μ²­ μœ„μ‘°λŠ” νŠΉμ • μ›Ήμ‚¬μ΄νŠΈκ°€ μ‚¬μš©μžμ˜ μ›Ή λΈŒλΌμš°μ €λ₯Ό μ‹ μš©ν•˜λŠ” μƒνƒœλ₯Ό λ…Έλ¦° 것
    • 일단 μ‚¬μš©μžκ°€ μ›Ήμ‚¬μ΄νŠΈμ— λ‘œκ·ΈμΈν•œ μƒνƒœμ—μ„œ μ‚¬μ΄νŠΈκ°„ μš”μ²­ μœ„μ‘° 곡격 μ½”λ“œκ°€ μ‚½μž…λœ νŽ˜μ΄μ§€λ₯Ό μ—΄λ©΄, 곡격 λŒ€μƒμ΄ λ˜λŠ” μ›Ήμ‚¬μ΄νŠΈλŠ” μœ„μ‘°λœ 곡격 λͺ…령이 믿을 수 μžˆλŠ” μ‚¬μš©μžλ‘œλΆ€ν„° λ°œμ†‘λœ κ²ƒμœΌλ‘œ νŒλ‹¨ν•˜κ²Œ λ˜μ–΄ 곡격에 λ…ΈμΆœλ¨

CORS λ™μž‘ 원리

  • 기본적으둜 μ›Ή ν΄λΌμ΄μ–ΈνŠΈ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ λ‹€λ₯Έ 좜처의 λ¦¬μ†ŒμŠ€λ₯Ό μš”μ²­ν•  λ•ŒλŠ” HTTP ν”„λ‘œν† μ½œμ„ μ‚¬μš©ν•˜μ—¬ μš”μ²­μ„ λ³΄λ‚΄κ²Œ λ˜λŠ”λ°, μ΄λ•Œ λΈŒλΌμš°μ €λŠ” μš”μ²­ 헀더에 Originμ΄λΌλŠ” ν•„λ“œμ— μš”μ²­μ„ λ³΄λ‚΄λŠ” 좜처λ₯Ό ν•¨κ»˜ 담아보냄
    • Origin: https://velog.io/@hwaya2828
  • 이후 μ„œλ²„κ°€ 이 μš”μ²­μ— λŒ€ν•œ 응닡을 ν•  λ•Œ 응닡 ν—€λ”μ˜ Access-Control-Allow-Originμ΄λΌλŠ” 값에 β€œμ΄ λ¦¬μ†ŒμŠ€λ₯Ό μ ‘κ·Όν•˜λŠ” 것이 ν—ˆμš©λœ μΆœμ²˜β€λ₯Ό λ‚΄λ €μ£Όκ³ , 이후 응닡을 받은 λΈŒλΌμš°μ €λŠ” μžμ‹ μ΄ λ³΄λƒˆλ˜ μš”μ²­μ˜ Originκ³Ό μ„œλ²„κ°€ 보내쀀 μ‘λ‹΅μ˜ Access-Control-Allow-Origin을 비ꡐ해본 ν›„ 이 응닡이 μœ νš¨ν•œ 응닡인지 μ•„λ‹Œμ§€λ₯Ό κ²°μ •
  • 기본적인 흐름은 μ΄λ ‡μ§€λ§Œ CORSκ°€ λ™μž‘ν•˜λŠ” 방식은 ν•œ 가지가 μ•„λ‹ˆλΌ μ„Έ κ°€μ§€μ˜ μ‹œλ‚˜λ¦¬μ˜€μ— 따라 변경됨

Preflight Request

  • ν”„λ¦¬ν”ŒλΌμ΄νŠΈ(Preflight) 방식은 일반적으둜 μš°λ¦¬κ°€ μ›Ή μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ κ°œλ°œν•  λ•Œ κ°€μž₯ ν”νžˆ λ§ˆμ£ΌμΉ˜λŠ” μ‹œλ‚˜λ¦¬μ˜€
  • 이 μ‹œλ‚˜λ¦¬μ˜€μ— ν•΄λ‹Ήν•˜λŠ” 상황일 λ•Œ λΈŒλΌμš°μ €λŠ” μš”μ²­μ„ ν•œλ²ˆμ— 보내지 μ•Šκ³  μ˜ˆλΉ„ μš”μ²­κ³Ό λ³Έ μš”μ²­μœΌλ‘œ λ‚˜λˆ„μ–΄μ„œ μ„œλ²„λ‘œ 전솑
    • μ΄λ•Œ λΈŒλΌμš°μ €κ°€ λ³Έ μš”μ²­μ„ 보내기 전에 λ³΄λ‚΄λŠ” μ˜ˆλΉ„ μš”μ²­μ„ Preflight라고 λΆ€λ₯΄λŠ” 것이며, 이 μ˜ˆλΉ„ μš”μ²­μ—λŠ” HTTP λ©”μ†Œλ“œ 쀑 OPTIONS λ©”μ†Œλ“œκ°€ μ‚¬μš©
    • μ˜ˆλΉ„ μš”μ²­μ˜ 역할은 λ³Έ μš”μ²­μ„ 보내기 전에 λΈŒλΌμš°μ € 슀슀둜 이 μš”μ²­μ„ λ³΄λ‚΄λŠ” 것이 μ•ˆμ „ν•œμ§€ ν™•μΈν•˜λŠ” 것

  • μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ fetch APIλ₯Ό μ‚¬μš©ν•˜μ—¬ λΈŒλΌμš°μ €μ—κ²Œ λ¦¬μ†ŒμŠ€λ₯Ό λ°›μ•„μ˜€λΌλŠ” λͺ…령을 내리면 λΈŒλΌμš°μ €λŠ” μ„œλ²„μ—κ²Œ μ˜ˆλΉ„ μš”μ²­μ„ λ¨Όμ € 보내고, μ„œλ²„λŠ” 이 μ˜ˆλΉ„ μš”μ²­μ— λŒ€ν•œ μ‘λ‹΅μœΌλ‘œ ν˜„μž¬ μžμ‹ μ΄ μ–΄λ–€ 것듀을 ν—ˆμš©ν•˜κ³ , μ–΄λ–€ 것듀을 κΈˆμ§€ν•˜κ³  μžˆλŠ”μ§€μ— λŒ€ν•œ 정보λ₯Ό 응닡 헀더에 λ‹΄μ•„μ„œ λΈŒλΌμš°μ €μ—κ²Œ λ‹€μ‹œ λ³΄λ‚΄μ£Όκ²Œ 됨
  • 이후 λΈŒλΌμš°μ €λŠ” μžμ‹ μ΄ 보낸 μ˜ˆλΉ„ μš”μ²­κ³Ό μ„œλ²„κ°€ 응닡에 λ‹΄μ•„μ€€ ν—ˆμš© 정책을 λΉ„κ΅ν•œ ν›„, 이 μš”μ²­μ„ λ³΄λ‚΄λŠ” 것이 μ•ˆμ „ν•˜λ‹€κ³  νŒλ‹¨λ˜λ©΄ 같은 μ—”λ“œν¬μΈνŠΈλ‘œ λ‹€μ‹œ λ³Έ μš”μ²­μ„ λ³΄λ‚΄κ²Œ 됨
  • 이후 μ„œλ²„κ°€ 이 λ³Έ μš”μ²­μ— λŒ€ν•œ 응닡을 ν•˜λ©΄ λΈŒλΌμš°μ €λŠ” μ΅œμ’…μ μœΌλ‘œ 이 응닡 데이터λ₯Ό μžλ°”μŠ€ν¬λ¦½νŠΈμ—κ²Œ λ„˜κ²¨μ€Œ
  • μ˜ˆλΉ„ μš”μ²­μ— λŒ€ν•œ μ‘λ‹΅μ—μ„œ μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•Šκ³  μ •μƒμ μœΌλ‘œ 200이 λ–¨μ–΄μ‘ŒλŠ”λ°, CORS 정책을 μœ„λ°˜ν–ˆλ‹€κ³  μ½˜μ†” μ°½μ—λŠ” λΉ¨κ°›κ²Œ μ—λŸ¬κ°€ ν‘œμ‹œλ  λ•Œ ν—·κ°ˆλ¦΄ 수 μžˆλŠ”λ° λΈŒλΌμš°μ €κ°€ CORS μ •μ±… μœ„λ°˜ μ—¬λΆ€λ₯Ό νŒλ‹¨ν•˜λŠ” μ‹œμ μ€ μ˜ˆλΉ„ μš”μ²­μ— λŒ€ν•œ 응닡을 받은 이후이기 λ•Œλ¬Έμ— CORS μ •μ±… μœ„λ°˜μœΌλ‘œ μΈν•œ μ—λŸ¬λŠ” μ˜ˆλΉ„ μš”μ²­μ˜ 성곡 여뢀와 별 상관이 μ—†μŒ
  • λ¬Όλ‘  μ˜ˆλΉ„ μš”μ²­ μžμ²΄κ°€ μ‹€νŒ¨ν•΄λ„ λ˜‘κ°™μ΄ CORS μ •μ±… μœ„λ°˜μœΌλ‘œ 처리될 μˆ˜λ„ μžˆμ§€λ§Œ, μ€‘μš”ν•œ 것은 μ˜ˆλΉ„ μš”μ²­μ˜ μ„±κ³΅μ΄λ‚˜ μ‹€νŒ¨ μ—¬λΆ€κ°€ μ•„λ‹ˆλΌ β€œμ‘λ‹΅ 헀더에 μœ νš¨ν•œ Access-Control-Allow-Origin 값이 μ‘΄μž¬ν•˜λŠ”κ°€β€μž„
    • λ§Œμ•½ μ˜ˆλΉ„ μš”μ²­μ΄ μ‹€νŒ¨ν•΄μ„œ 200이 μ•„λ‹Œ μƒνƒœ μ½”λ“œκ°€ λ‚΄λ €μ˜€λ”λΌλ„ 헀더에 μ € 값이 μ œλŒ€λ‘œ λ“€μ–΄κ°€μžˆλ‹€λ©΄ CORS μ •μ±… μœ„λ°˜μ΄ μ•„λ‹ˆλΌλŠ” 의미
  • λŒ€λΆ€λΆ„μ˜ 경우 μ΄λ ‡κ²Œ μ˜ˆλΉ„ μš”μ²­κ³Ό λ³Έ μš”μ²­μ„ λ‚˜λˆ„μ–΄ λ³΄λ‚΄λŠ” ν”„λ¦¬ν”ŒλΌμ΄νŠΈ 방식을 μ‚¬μš©ν•˜κΈ°λŠ” ν•˜μ§€λ§Œ, λͺ¨λ“  μƒν™©μ—μ„œ μ΄λ ‡κ²Œ 두 λ²ˆμ”© μš”μ²­μ„ λ³΄λ‚΄λŠ” 것은 μ•„λ‹˜
    • 쑰금 κΉŒλ‹€λ‘œμš΄ μ‘°κ±΄μ΄κΈ°λŠ” ν•˜μ§€λ§Œ μ–΄λ–€ κ²½μš°μ—λŠ” μ˜ˆλΉ„ μš”μ²­ 없이 λ³Έ μš”μ²­λ§ŒμœΌλ‘œ CORS μ •μ±… μœ„λ°˜ μ—¬λΆ€λ₯Ό κ²€μ‚¬ν•˜κΈ°λ„ 함

Simple Request

  • 이 μ‹œλ‚˜λ¦¬μ˜€μ— λŒ€ν•œ 정식 λͺ…칭은 μ—†μ§€λ§Œ MDN의 CORS λ¬Έμ„œμ—μ„œλŠ” 이 μ‹œλ‚˜λ¦¬μ˜€λ₯Ό λ‹¨μˆœ μš”μ²­(Simple Request)라고 λΆ€λ₯΄κ³  있음
  • λ‹¨μˆœ μš”μ²­μ€ μ˜ˆλΉ„ μš”μ²­μ„ 보내지 μ•Šκ³  λ°”λ‘œ μ„œλ²„μ—κ²Œ λ³Έ μš”μ²­λΆ€ν„° 보낸 ν›„, μ„œλ²„κ°€ 이에 λŒ€ν•œ μ‘λ‹΅μ˜ 헀더에 Access-Control-Allow-Originκ³Ό 같은 값을 보내주면 κ·Έλ•Œ λΈŒλΌμš°μ €κ°€ CORS μ •μ±… μœ„λ°˜ μ—¬λΆ€λ₯Ό κ²€μ‚¬ν•˜λŠ” 방식
    • 즉, ν”„λ¦¬ν”ŒλΌμ΄νŠΈμ™€ λ‹¨μˆœ μš”μ²­ μ‹œλ‚˜λ¦¬μ˜€λŠ” μ „λ°˜μ μΈ 둜직 μžμ²΄λŠ” κ°™λ˜ μ˜ˆλΉ„ μš”μ²­μ˜ 쑴재 유무만 닀름

  • ν•˜μ§€λ§Œ 아무 λ•Œλ‚˜ λ‹¨μˆœ μš”μ²­μ„ μ‚¬μš©ν•  수 μžˆλŠ” 것은 μ•„λ‹ˆκ³  νŠΉμ • 쑰건을 λ§Œμ‘±ν•˜λŠ” κ²½μš°μ—λ§Œ μ˜ˆλΉ„ μš”μ²­μ„ μƒλž΅ν•  수 μžˆλŠ”λ°, 이 쑰건이 쑰금 κΉŒλ‹€λ‘­κΈ° λ•Œλ¬Έμ— 일반적인 λ°©λ²•μœΌλ‘œ μ›Ή μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜ μ•„ν‚€ν…μ²˜λ₯Ό μ„€κ³„ν•˜κ²Œ 되면 거의 μΆ©μ‘±μ‹œν‚€κΈ° 어렀움
    • 쑰건
      • μš”μ²­μ˜ λ©”μ†Œλ“œλŠ” GET, HEAD, POST 쀑 ν•˜λ‚˜μ—¬μ•Ό 함
      • Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Widthλ₯Ό μ œμ™Έν•œ 헀더λ₯Ό μ‚¬μš©ν•˜λ©΄ μ•ˆλ¨
      • λ§Œμ•½ Content-Typeλ₯Ό μ‚¬μš©ν•˜λŠ” κ²½μš°μ—λŠ” application/x-www-form-urlencoded, multipart/form-data, text/plain만 ν—ˆμš©
  • 쑰건에 λͺ…μ‹œλœ 헀더듀은 μ§„μ§œ 기본적인 헀더듀이기 λ•Œλ¬Έμ—, λ³΅μž‘ν•œ μƒμš© μ›Ή μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ 이 헀더듀 외에 좔가적인 헀더λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” κ²½μš°λŠ” λ“œλ­„
    • μ‚¬μš©μž 인증에 μ‚¬μš©λ˜λŠ” Authorization 헀더 μ‘°μ°¨ 쑰건에 ν¬ν•¨λ˜μ§€ μ•ŠμŒ
  • λ˜ν•œ λŒ€λΆ€λΆ„μ˜ HTTP APIλŠ” text/xmlμ΄λ‚˜ application/json 컨텐츠 νƒ€μž…μ„ 가지도둝 μ„€κ³„λ˜κΈ° λ•Œλ¬Έμ— 사싀상 이 쑰건듀을 λͺ¨λ‘ λ§Œμ‘±μ‹œν‚€λŠ” 상황을 λ§Œλ“€κΈ°λŠ” κ·Έλ ‡κ²Œ 쉽지 μ•Šμ€ 것이 ν˜„μ‹€

Credentialed Request

  • 인증된 μš”μ²­μ„ μ‚¬μš©ν•˜λŠ” 방법
    • 이 μ‹œλ‚˜λ¦¬μ˜€λŠ” CORS의 기본적인 방식이라기 λ³΄λ‹€λŠ” λ‹€λ₯Έ 좜처 κ°„ ν†΅μ‹ μ—μ„œ μ’€ 더 λ³΄μ•ˆμ„ κ°•ν™”ν•˜κ³  싢을 λ•Œ μ‚¬μš©ν•˜λŠ” 방법
  • 기본적으둜 λΈŒλΌμš°μ €κ°€ μ œκ³΅ν•˜λŠ” 비동기 λ¦¬μ†ŒμŠ€ μš”μ²­ API인 XMLHttpRequest κ°μ²΄λ‚˜ fetch APIλŠ” λ³„λ„μ˜ μ˜΅μ…˜ 없이 λΈŒλΌμš°μ €μ˜ μΏ ν‚€ μ •λ³΄λ‚˜ 인증과 κ΄€λ ¨λœ 헀더λ₯Ό ν•¨λΆ€λ‘œ μš”μ²­μ— 담지 μ•ŠλŠ”λ°, μ΄λ•Œ μš”μ²­μ— 인증과 κ΄€λ ¨λœ 정보λ₯Ό 담을 수 있게 ν•΄μ£ΌλŠ” μ˜΅μ…˜μ΄ λ°”λ‘œ credentials μ˜΅μ…˜μž„

    • credentials μ˜΅μ…˜μ—λŠ” 3가지 값이 쑴재

      μ˜΅μ…˜ κ°’μ„€λͺ…
      same-origin (κΈ°λ³Έκ°’)같은 좜처 κ°„ μš”μ²­μ—λ§Œ 인증 정보λ₯Ό 담을 수 있음
      includeλͺ¨λ“  μš”μ²­μ— 인증 정보λ₯Ό 담을 수 있음
      omitλͺ¨λ“  μš”μ²­μ— 인증 정보λ₯Ό 담지 μ•ŠμŒ
    • same-originμ΄λ‚˜ include와 같은 μ˜΅μ…˜μ„ μ‚¬μš©ν•˜μ—¬ λ¦¬μ†ŒμŠ€ μš”μ²­μ— 인증 정보가 ν¬ν•¨λ˜λ©΄ λΈŒλΌμš°μ €λŠ” λ‹€λ₯Έ 좜처의 λ¦¬μ†ŒμŠ€λ₯Ό μš”μ²­ν•  λ•Œ λ‹¨μˆœνžˆ Access-Control-Allow-Origin만 ν™•μΈν•˜λŠ” 것이 μ•„λ‹ˆλΌ μ’€ 더 λΉ‘λΉ‘ν•œ 검사 쑰건을 μΆ”κ°€ν•˜κ²Œ 됨

  • μš”μ²­μ— 인증 정보가 λ‹΄κ²¨μžˆλŠ” μƒνƒœμ—μ„œ λ‹€λ₯Έ 좜처의 λ¦¬μ†ŒμŠ€λ₯Ό μš”μ²­ν•˜κ²Œ 되면 λΈŒλΌμš°μ €λŠ” CORS μ •μ±… μœ„λ°˜ μ—¬λΆ€λ₯Ό κ²€μ‚¬ν•˜λŠ” 룰에 λ‹€μŒ 두 가지λ₯Ό μΆ”κ°€ν•˜κ²Œ 됨
    • Access-Control-Allow-Originμ—λŠ” *λ₯Ό μ‚¬μš©ν•  수 μ—†μœΌλ©°, λͺ…μ‹œμ μΈ URL이어야 함
    • 응닡 ν—€λ”μ—λŠ” λ°˜λ“œμ‹œ Access-Control-Allow-Credentials: trueκ°€ μ‘΄μž¬ν•΄μ•Όν•¨

CORS ν•΄κ²° 방법

  • CORS λ™μž‘ 원리λ₯Ό 보면 μ„œλ²„μ—μ„œ Access-Control-Allow-Origin 헀더λ₯Ό ν¬ν•¨ν•œ 응닡을 λΈŒλΌμš°μ €μ— λ³΄λ‚΄λŠ” λ°©μ‹μœΌλ‘œ CORS μ—λŸ¬λ₯Ό ν•΄κ²°ν•  수 있음
    • CORS μ—λŸ¬λ₯Ό ν™•μΈν–ˆλ‹€λ©΄ μ„œλ²„μ—μ„œ Access-Control-Allow-Origin λ“± CORSλ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•œ λͺ‡ 가지 응닡 헀더λ₯Ό ν¬ν•¨μ‹œμΌœμ•Ό 함
    • ν”„λ ˆμž„μ›Œν¬μ— 따라 CORSλ₯Ό ν•΄κ²°ν•΄ μ£ΌλŠ” 라이브러리 쑴재

HTTP 응닡 헀더

  • 라이브러리λ₯Ό μ‚¬μš©ν•˜λ©΄ κ°„λ‹¨ν•˜κ²Œ CORSλ₯Ό ν•΄κ²°ν•  수 μžˆμ§€λ§Œ, CORSλ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•œ 응닡 헀더가 무엇이 μžˆλŠ”μ§€ μ•Œκ³  있으면 μ’‹μŒ
  • Access-Control-Allow-Origin: <origin> | *
    • Access-Control-Allow-Origin 헀더에 μž‘μ„±λœ 좜처만 λΈŒλΌμš°μ €κ°€ λ¦¬μ†ŒμŠ€λ₯Ό μ ‘κ·Όν•  수 μžˆλ„λ‘ ν—ˆμš©ν•¨
    • μ‚¬μš© 방법
      • Access-Control-Allow-Origin: https://velog.io/@hwaya2828
        • λΈŒλΌμš°μ €λŠ” https://velog.io/@hwaya2828 μ—μ„œ μ„œλ²„ μ‘λ‹΅μœΌλ‘œ 온 λ¦¬μ†ŒμŠ€μ— μ ‘κ·Όν•  수 있음
      • Access-Control-Allow-Origin: *
        • λΈŒλΌμš°μ €λŠ” μΆœμ²˜μ— 상관없이 λͺ¨λ“  λ¦¬μ†ŒμŠ€μ— μ ‘κ·Όν•  수 있음
  • Access-Control-Allow-Methods: <method>[, <method>]
    • λΈŒλΌμš°μ €μ—μ„œ λ³΄λ‚΄λŠ” μš”μ²­ 헀더에 ν¬ν•¨λœ Access-Control-Request-Method 에 λŒ€ν•œ 응닡 결과둜, λ¦¬μ†ŒμŠ€ 접근을 ν—ˆμš©ν•˜λŠ” HTTP λ©”μ„œλ“œλ₯Ό 지정해 μ£ΌλŠ” 헀더
    • μ‚¬μš© 방법
      • Access-Control-Allow-Methods: GET, PUT
        • GET, PUT, POST, DELETE λ“±μ˜ HTTP λ©”μ„œλ“œλ₯Ό ,둜 κ΅¬λΆ„ν•˜μ—¬ λ„˜κ²¨μ€Œ
  • Access-Control-Expose-Headers: <header-name>[, <header-name>]
    • μ„œλ²„μ—μ„œ 응닡 헀더에 Access-Control-Expose-Headersλ₯Ό μΆ”κ°€ν•΄μ•Ό λΈŒλΌμš°μ €μ˜ μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ 헀더에 μ ‘κ·Όν•  수 있음
    • μ‚¬μš© 방법
      • Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
        • ,둜 κ΅¬λΆ„ν•˜μ—¬ μ—¬λŸ¬ 개의 헀더λ₯Ό 넣을 수 있음
  • Access-Control-Allow-Headers: <header-name>[, <header-name>
    • λΈŒλΌμš°μ €μ—μ„œ λ³΄λ‚΄λŠ” μš”μ²­ 헀더에 ν¬ν•¨λœ Access-Control-Request-Headers 헀더에 λŒ€ν•œ 응닡 κ²°κ³Ό
    • μ‚¬μš© 방법
      • Access-Control-Allow-Headers: X-Custom-Request
        • μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ μ»€μŠ€ν…€ 헀더λ₯Ό μ„œλ²„μ— μ „λ‹¬ν•˜λ©΄ OPTIONS μš”μ²­ ν—€λ”μ˜ Access-Control-Request-Headers 헀더에 μ»€μŠ€ν…€ 헀더 이름이 μΆ”κ°€λ˜λŠ”λ°, μ„œλ²„μ—μ„œλŠ” Access-Control-Request-Headers에 μž‘μ„±λœ 값을 보고 Access-Control-Allow-Headers 응닡 헀더에 μ»€μŠ€ν…€ 헀더 이름을 λͺ…μ‹œν•΄μ€˜μ•Ό 함
  • Access-Control-Max-Age: <delta-seconds>
    • Preflight μš”μ²­ κ²°κ³Όλ₯Ό μΊμ‹œ ν•  수 μžˆλŠ” μ‹œκ°„μ„ λ‚˜νƒ€λƒ„
    • μ‚¬μš© 방법
      • Access-Control-Max-Age: 60
        • 초 λ‹¨μœ„λ‘œ μΊμ‹œ μ‹œκ°„μ„ μ„€μ •ν•  수 있으며, μœ„μ˜ μ½”λ“œλŠ” 60초 λ™μ•ˆ preflight μš”μ²­μ„ μΊμ‹œ ν•˜λŠ” μ½”λ“œμ΄κΈ° λ•Œλ¬Έμ— 60초 λ™μ•ˆ OPTIONS λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” μ˜ˆλΉ„ μš”μ²­μ„ 보내지 μ•ŠμŒ
  • Access-Control-Allow-Credentials: true
    • μžλ°”μŠ€ν¬λ¦½νŠΈ μš”μ²­μ—μ„œ credentialsκ°€ include일 λ•Œ μš”μ²­μ— λŒ€ν•œ 응닡을 ν•  수 μžˆλŠ”μ§€λ₯Ό λ‚˜νƒ€λ‚΄λ©°, false둜 μ„€μ •ν•΄ μ£Όκ³  싢을 κ²½μš°μ—λŠ” 헀더λ₯Ό μƒλž΅ν•˜λ©΄ 됨
    • μ‚¬μš© 방법
      • Access-Control-Allow-Credentials: true

HTTP μš”μ²­ 헀더

  • μš”μ²­ 헀더듀은 λ³„λ„λ‘œ λͺ…μ‹œν•΄ 주지 μ•Šμ•„λ„ λΈŒλΌμš°μ €μ—μ„œ OPTIONS μš”μ²­μ— 좔가함
  • Origin: <origin>
    • Origin ν—€λ”λŠ” μš”μ²­ν•˜λŠ” λŒ€μƒμ˜ 좜처λ₯Ό λ‚˜νƒ€λƒ„
    • APIλ₯Ό ν˜ΈμΆœν•˜λŠ” νŽ˜μ΄μ§€μ˜ 좜처 값이 μ €μž₯됨
  • Access-Control-Request-Method: <method>
    • Access-Control-Request-Method ν—€λ”λŠ” μ‹€μ œ μš”μ²­μ΄ μ–΄λ–€ HTTP λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ”μ§€ μ„œλ²„μ— μ•Œλ €μ£ΌκΈ° μœ„ν•΄ μ‚¬μš©λ¨
  • Access-Control-Request-Headers: <field-name>[, <field-name>]
    • Access-Control-Request-Headers ν—€λ”λŠ” λΈŒλΌμš°μ €μ—μ„œ λ³΄λ‚΄λŠ” μ»€μŠ€ν…€ 헀더 이름을 μ„œλ²„μ— μ•Œλ €μ£ΌκΈ° μœ„ν•΄ μ‚¬μš©λ¨
profile
🌱 Backend-Dev | hwaya2828@gmail.com

0개의 λŒ“κΈ€