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/@hwaya2828
Access-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/@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
Access-Control-Allow-Credentials: true
credentials
κ° include
μΌ λ μμ²μ λν μλ΅μ ν μ μλμ§λ₯Ό λνλ΄λ©°, false
λ‘ μ€μ ν΄ μ£Όκ³ μΆμ κ²½μ°μλ ν€λλ₯Ό μλ΅νλ©΄ λ¨Access-Control-Allow-Credentials: true
OPTIONS
μμ²μ μΆκ°ν¨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
ν€λλ λΈλΌμ°μ μμ 보λ΄λ 컀μ€ν
ν€λ μ΄λ¦μ μλ²μ μλ €μ£ΌκΈ° μν΄ μ¬μ©λ¨