
CORSλ Cross-Origin Resource Sharingμ μ½μ
Protocolκ³Ό Host, Portλ₯Ό λͺ¨λ ν©μΉ κ²μ μλ―Έhttps://google.com:443κ³Ό κ°μ΄ μΆμ²μ ν¬νΈ λ²νΈκ° λͺ
μμ μΌλ‘ ν¬ν¨λμ΄ μλ€λ©΄ μ΄ ν¬νΈ λ²νΈκΉμ§ λͺ¨λ μΌμΉν΄μΌ κ°μ μΆμ²λΌκ³ μΈμ origin νλ‘νΌν°μ μ κ·Όν¨μΌλ‘μ¨ μ€νλκ³ μλ μΆμ²λ₯Ό μμλΌ μ μμνμ¬ μΉνμ΄μ§μ μ£Όμκ° 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κ° λμκ°λ λ°©μμ μ νν λͺ¨λ₯΄λ©΄ μλ¬ νΈλ μ΄μ±μ λνμ κ²ͺμ μλ μμCORS, κ·Έλ¦¬κ³ λ ν κ°μ§λ SOP(Same-Origin Policy)SOPλ 2011λ
, RFC 6454μμ μ²μ λ±μ₯ν 보μ μ μ±
μΌλ‘ λ§ κ·Έλλ‘ βκ°μ μΆμ²μμλ§ λ¦¬μμ€λ₯Ό 곡μ ν μ μλ€βλΌλ κ·μΉμ κ°μ§ μ μ±
CORS μ μ±
μ μ§ν¨ 리μμ€ μμ²βCORSλΌλ μ΄λ¦μ΄ μ²μ λ±μ₯ν κ²μ 2009λ
μ΄λΌ, SOPμ λ±μ₯λ³΄λ€ λΉ λ¦SOP μ μ±
μ μλ°ν κ²μ΄ λκ³ , κ±°κΈ°λ€κ° SOPμ μμΈ μ‘°νμΈ CORS μ μ±
κΉμ§ μ§ν€μ§ μλλ€λ©΄ μμ λ€λ₯Έ μΆμ²μ 리μμ€λ₯Ό μ¬μ©ν μ μκ² λλ κ²SOPμμ μ μλ μμΈ μ‘°νκ³Ό CORSλ₯Ό μ¬μ©ν μ μλ μΌμ΄μ€λ€μ΄ λ§λ¬Όλ¦¬μ§ μμ κ²½μ°μλ μμ 리μμ€ μμ²μ ν μ μλ μΌμ΄μ€λ μ‘΄μ¬ν μ μμXSSλ XSRF λ±μ 보μ μ·¨μ½μ μ λ
Έλ¦° 곡격μ λ°©μ΄ν μ μμTip! XSSλ?
- μ¬μ΄νΈ κ° μ€ν¬λ¦½ν (cross-site scripting, XSS)μ μΉ μ ν리μΌμ΄μ μμ λ§μ΄ λνλλ μ·¨μ½μ μ νλλ‘ μΉμ¬μ΄νΈ κ΄λ¦¬μκ° μλ μ΄κ° μΉ νμ΄μ§μ μ μ± μ€ν¬λ¦½νΈλ₯Ό μ½μ ν μ μλ μ·¨μ½μ
- μ£Όλ‘ μ¬λ¬ μ¬μ©μκ° λ³΄κ² λλ μ μ κ²μνμ μ μ± μ€ν¬λ¦½νΈκ° λ΄κΈ΄ κΈμ μ¬λ¦¬λ ννλ‘ μ΄λ£¨μ΄μ§
- μ΄ μ·¨μ½μ μ μΉ μ ν리μΌμ΄μ μ΄ μ¬μ©μλ‘λΆν° μ λ ₯ λ°μ κ°μ μ λλ‘ κ²μ¬νμ§ μκ³ μ¬μ©ν κ²½μ° λνλ¨
- μ΄ μ·¨μ½μ μΌλ‘ ν΄μ»€κ° μ¬μ©μμ μ 보(μΏ ν€, μΈμ λ±)λ₯Ό νμ·¨νκ±°λ, μλμΌλ‘ λΉμ μμ μΈ κΈ°λ₯μ μννκ² ν μ μμ
- μ£Όλ‘ λ€λ₯Έ μΉμ¬μ΄νΈμ μ 보λ₯Ό κ΅ννλ μμΌλ‘ μλνλ―λ‘ μ¬μ΄νΈ κ° μ€ν¬λ¦½ν μ΄λΌκ³ ν¨
Tip! XSRFλ?
- μ¬μ΄νΈ κ° μμ² μμ‘°(Cross-site request forgery, CSRF, XSRF)λ μΉμ¬μ΄νΈ μ·¨μ½μ 곡격μ νλλ‘, μ¬μ©μκ° μμ μ μμ§μλ 무κ΄νκ² κ³΅κ²©μκ° μλν νμ(μμ , μμ , λ±λ‘ λ±)λ₯Ό νΉμ μΉμ¬μ΄νΈμ μμ²νκ² νλ 곡격μ λ§ν¨
- μ λͺ κ²½λ§€ μ¬μ΄νΈμΈ μ₯μ μμ λ°μν κ°μΈμ 보 μ μΆ μ¬κ±΄μμ μ¬μ©λ 곡격 λ°©μ μ€ νλ
- μ¬μ΄νΈ κ° μ€ν¬λ¦½ν (XSS)μ μ΄μ©ν κ³΅κ²©μ΄ μ¬μ©μκ° νΉμ μΉμ¬μ΄νΈλ₯Ό μ μ©νλ μ μ λ Έλ¦° κ²μ΄λΌλ©΄, μ¬μ΄νΈκ° μμ² μμ‘°λ νΉμ μΉμ¬μ΄νΈκ° μ¬μ©μμ μΉ λΈλΌμ°μ λ₯Ό μ μ©νλ μνλ₯Ό λ Έλ¦° κ²
- μΌλ¨ μ¬μ©μκ° μΉμ¬μ΄νΈμ λ‘κ·ΈμΈν μνμμ μ¬μ΄νΈκ° μμ² μμ‘° 곡격 μ½λκ° μ½μ λ νμ΄μ§λ₯Ό μ΄λ©΄, 곡격 λμμ΄ λλ μΉμ¬μ΄νΈλ μμ‘°λ 곡격 λͺ λ Ήμ΄ λ―Ώμ μ μλ μ¬μ©μλ‘λΆν° λ°μ‘λ κ²μΌλ‘ νλ¨νκ² λμ΄ κ³΅κ²©μ λ ΈμΆλ¨
Originμ΄λΌλ νλμ μμ²μ 보λ΄λ μΆμ²λ₯Ό ν¨κ» λ΄μ보λOrigin: https://velog.io/@hwaya2828Access-Control-Allow-Originμ΄λΌλ κ°μ βμ΄ λ¦¬μμ€λ₯Ό μ κ·Όνλ κ²μ΄ νμ©λ μΆμ²βλ₯Ό λ΄λ €μ£Όκ³ , μ΄ν μλ΅μ λ°μ λΈλΌμ°μ λ μμ μ΄ λ³΄λλ μμ²μ Originκ³Ό μλ²κ° 보λ΄μ€ μλ΅μ Access-Control-Allow-Originμ λΉκ΅ν΄λ³Έ ν μ΄ μλ΅μ΄ μ ν¨ν μλ΅μΈμ§ μλμ§λ₯Ό κ²°μ CORSκ° λμνλ λ°©μμ ν κ°μ§κ° μλλΌ μΈ κ°μ§μ μλ리μ€μ λ°λΌ λ³κ²½λ¨ν리νλΌμ΄νΈ(Preflight) λ°©μμ μΌλ°μ μΌλ‘ μ°λ¦¬κ° μΉ μ΄ν리μΌμ΄μ
μ κ°λ°ν λ κ°μ₯ νν λ§μ£ΌμΉλ μλ리μ€PreflightλΌκ³ λΆλ₯΄λ κ²μ΄λ©°, μ΄ μλΉ μμ²μλ HTTP λ©μλ μ€ OPTIONS λ©μλκ° μ¬μ©
fetch APIλ₯Ό μ¬μ©νμ¬ λΈλΌμ°μ μκ² λ¦¬μμ€λ₯Ό λ°μμ€λΌλ λͺ
λ Ήμ λ΄λ¦¬λ©΄ λΈλΌμ°μ λ μλ²μκ² μλΉ μμ²μ λ¨Όμ 보λ΄κ³ , μλ²λ μ΄ μλΉ μμ²μ λν μλ΅μΌλ‘ νμ¬ μμ μ΄ μ΄λ€ κ²λ€μ νμ©νκ³ , μ΄λ€ κ²λ€μ κΈμ§νκ³ μλμ§μ λν μ 보λ₯Ό μλ΅ ν€λμ λ΄μμ λΈλΌμ°μ μκ² λ€μ 보λ΄μ£Όκ² λ¨CORS μ μ±
μ μλ°νλ€κ³ μ½μ μ°½μλ λΉ¨κ°κ² μλ¬κ° νμλ λ ν·κ°λ¦΄ μ μλλ° λΈλΌμ°μ κ° CORS μ μ±
μλ° μ¬λΆλ₯Ό νλ¨νλ μμ μ μλΉ μμ²μ λν μλ΅μ λ°μ μ΄νμ΄κΈ° λλ¬Έμ CORS μ μ±
μλ°μΌλ‘ μΈν μλ¬λ μλΉ μμ²μ μ±κ³΅ μ¬λΆμ λ³ μκ΄μ΄ μμCORS μ μ±
μλ°μΌλ‘ μ²λ¦¬λ μλ μμ§λ§, μ€μν κ²μ μλΉ μμ²μ μ±κ³΅μ΄λ μ€ν¨ μ¬λΆκ° μλλΌ βμλ΅ ν€λμ μ ν¨ν Access-Control-Allow-Origin κ°μ΄ μ‘΄μ¬νλκ°βμ ν리νλΌμ΄νΈ λ°©μμ μ¬μ©νκΈ°λ νμ§λ§, λͺ¨λ μν©μμ μ΄λ κ² λ λ²μ© μμ²μ 보λ΄λ κ²μ μλ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 ν€λ μ‘°μ°¨ 쑰건μ ν¬ν¨λμ§ μμtext/xmlμ΄λ application/json 컨ν
μΈ νμ
μ κ°μ§λλ‘ μ€κ³λκΈ° λλ¬Έμ μ¬μ€μ μ΄ μ‘°κ±΄λ€μ λͺ¨λ λ§μ‘±μν€λ μν©μ λ§λ€κΈ°λ κ·Έλ κ² μ½μ§ μμ κ²μ΄ νμ€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 λμ μ리λ₯Ό 보면 μλ²μμ Access-Control-Allow-Origin ν€λλ₯Ό ν¬ν¨ν μλ΅μ λΈλΌμ°μ μ 보λ΄λ λ°©μμΌλ‘ CORS μλ¬λ₯Ό ν΄κ²°ν μ μμCORS μλ¬λ₯Ό νμΈνλ€λ©΄ μλ²μμ Access-Control-Allow-Origin λ± CORSλ₯Ό ν΄κ²°νκΈ° μν λͺ κ°μ§ μλ΅ ν€λλ₯Ό ν¬ν¨μμΌμΌ ν¨CORSλ₯Ό ν΄κ²°ν΄ μ£Όλ λΌμ΄λΈλ¬λ¦¬ μ‘΄μ¬CORSλ₯Ό ν΄κ²°ν μ μμ§λ§, CORSλ₯Ό ν΄κ²°νκΈ° μν μλ΅ ν€λκ° λ¬΄μμ΄ μλμ§ μκ³ μμΌλ©΄ μ’μAccess-Control-Allow-Origin: <origin> | *Access-Control-Allow-Origin ν€λμ μμ±λ μΆμ²λ§ λΈλΌμ°μ κ° λ¦¬μμ€λ₯Ό μ κ·Όν μ μλλ‘ νμ©ν¨Access-Control-Allow-Origin: https://velog.io/@hwaya2828https://velog.io/@hwaya2828 μμ μλ² μλ΅μΌλ‘ μ¨ λ¦¬μμ€μ μ κ·Όν μ μμAccess-Control-Allow-Origin: *Access-Control-Allow-Methods: <method>[, <method>]Access-Control-Request-Method μ λν μλ΅ κ²°κ³Όλ‘, 리μμ€ μ κ·Όμ νμ©νλ HTTP λ©μλλ₯Ό μ§μ ν΄ μ£Όλ ν€λAccess-Control-Allow-Methods: GET, PUTGET, 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-RequestOPTIONS μμ² ν€λμ Access-Control-Request-Headers ν€λμ 컀μ€ν
ν€λ μ΄λ¦μ΄ μΆκ°λλλ°, μλ²μμλ Access-Control-Request-Headersμ μμ±λ κ°μ λ³΄κ³ Access-Control-Allow-Headers μλ΅ ν€λμ 컀μ€ν
ν€λ μ΄λ¦μ λͺ
μν΄μ€μΌ ν¨Access-Control-Max-Age: <delta-seconds>Preflight μμ² κ²°κ³Όλ₯Ό μΊμ ν μ μλ μκ°μ λνλAccess-Control-Max-Age: 60Access-Control-Allow-Credentials: truecredentialsκ° includeμΌ λ μμ²μ λν μλ΅μ ν μ μλμ§λ₯Ό λνλ΄λ©°, falseλ‘ μ€μ ν΄ μ£Όκ³ μΆμ κ²½μ°μλ ν€λλ₯Ό μλ΅νλ©΄ λ¨Access-Control-Allow-Credentials: trueOPTIONS μμ²μ μΆκ°ν¨Origin: <origin>Origin ν€λλ μμ²νλ λμμ μΆμ²λ₯Ό λνλAccess-Control-Request-Method: <method>Access-Control-Request-Method ν€λλ μ€μ μμ²μ΄ μ΄λ€ HTTP λ©μλλ₯Ό μ¬μ©νλμ§ μλ²μ μλ €μ£ΌκΈ° μν΄ μ¬μ©λ¨Access-Control-Request-Headers: <field-name>[, <field-name>] Access-Control-Request-Headers ν€λλ λΈλΌμ°μ μμ 보λ΄λ 컀μ€ν
ν€λ μ΄λ¦μ μλ²μ μλ €μ£ΌκΈ° μν΄ μ¬μ©λ¨