
Origin(์ถ์ฒ)
URL์์ ํ์ธ ๊ฐ๋ฅํ ํ๋กํ ์ฝ, ํธ์คํธ, ํฌํธ ๊ฐ ๊ฐ์ ๋ ๊ฐ์ ์ถ์ฒ!
localhost ์ 127.0.0.1์ ๋ค๋ฅธ ํธ์คํธ๋ก ํ๋จ๋จ!(์ค์ ๋ก๋ ๊ฐ์ ์ฃผ์์ง๋ง)SOP(Same Origin Policy)
SOP๋ฅผ ์ฌ์ฉํ๋๊ฐ?SOP๋ฅผ ์ด์ฉํ๋ฉด Origin์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ์์ฒญ์ ๊ฑฐ์ ํ๋ค!hacker.ck์์ ์์ฒญ์ ๋ณด๋ธ๋ค. ์๋๋ instagram.com์์ ์์ฒญ์ด ์์ผ ํ๋ค!)๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ (Cross-Origin Resorce Sharing, CORS)
๋ค๋ฅธ
Origin(๋๋ฉ์ธ/ํ๋กํ ์ฝ..) ๋ฑ์ผ๋ก ๋ค์ด์ค๋์์ฒญ์ํ์ฉํด์ฃผ๋ ๊ฒ!
์ถ๊ฐ HTTP ํค๋๋ฅผ ์ฌ์ฉํด ํ ์ถ์ฒ์์ ์คํ ์ค์ธ ์น ์ดํ๋ฆฌ์ผ์ด์
์ด
๋ค๋ฅธ ์ถ์ฒ์ ์ ํํ ์์์ ์ ๊ทผํ ์ ์๋ ๊ถํ์ ๋ถ์ฌํ๋๋ก ๋ธ๋ผ์ฐ์ ์ ์๋ ค์ฃผ๋ ์ฒด์ !
Simple Request์ฌ์ ์์ฒญ(
Preflight) ์์ด! ๋ฐ๋ก ์์ฒญ์ ๋ ๋ฆผ!
ํ์์กฐ๊ฑด
GET, POST, HEAD ๋ฉ์๋ ์ค ํ๋์ฌ์ผ ํจAccept
Accept-Language
Content-Language
Content-Type
WebKit/Safari ๋ธ๋ผ์ฐ์ ์ ๊ฒฝ์ฐnonstandard ๊ฐ์ด ์กด์ฌํ๋ฉด,simple request๋ก ๊ฐ์ฃผํ์ง ์๋๋ค!POST ๋ฉ์๋์ ๊ฒฝ์ฐ, Content-Type(์์ฒญ ๋ฐ๋ ํ์
)์ด ๋ค์ ์ค ํ๋์ฌ์ผ ํจapplication/x-www-form-urlencoded
multipart/form-data
text/plain
Preflight Request
๋๋ค ์ง์ ๋๋ฌ๊ฐ๋ ๋ผ?
๋ณธ์์ฒญ์ ๋ณด๋ด๊ธฐ ์ , ์์ฒญ์ ๋ณด๋ด๋ ๋๋์ง Options ๋ฉ์๋๋ฅผ ํตํด ํ์ธ
๊ณผ์
preflight request)๋ก ์ด ์์ฒญ์ ๋ณด๋ด๋ ๋๋์ง ๋ฌผ์ด๋ด. ํค๋์ ๋ค์ ํญ๋ชฉ์ด ํฌํจ๋์ด์ผ ํจ"Origin" : ํด๋น ์์น์์ ์์ฒญ์ ๋ณด๋ธ๋ค๋ ๋ป
"Access-Control-Request-Method" : ์ด๋ค ๋ฉ์๋์ ์์ฒญ์ ๋ณด๋ผ๊ฑด์ง ๋ฌผ์ด๋ด
"Access-Control-Request-Headers" : ์ค์ ์์ฒญ์ ์ถ๊ฐ ํค๋๋ฅผ ๋ฌด์์ ๋ณด๋ผ ์ ์๋์ง ๋ฌผ์ด๋ด
preflight response)์ ๋ฐ๋๋ค. ์ด๋ ํค๋์ ๋ค์ ํญ๋ชฉ์ด ํฌํจ๋์ด์ผ ํจ"Access-Control-Allow-Origin" : ํด๋น `Origin`์ ํ๊ฐํ๋ค๋ ๋ป
"Access-Control-Allow-Methods" : ํด๋น `๋ฉ์๋`๋ค์ ์์ฒญ์ ํ๊ฐํ๋ค๋ ๋ป
"Access-Control-Allow-Headers" : ํด๋น `ํค๋`๋ค์ ํ๊ฐํ๋ค๋ ๋ป
"Access-Control-Max-Age" : ์๋ต์ `์บ์` ๊ธฐ๊ฐ, ํด๋น ์บ์๊ฐ ์์์ preflight ๊ณผ์ ์ ๊ฑด๋๋
์ค์ ์์ฒญ์ ๋ณด๋~์ค์ ์๋ต์ ๋ฐ์~Credentialed Request์๊ฒฉ์ฆ๋ช (์ฟ ํค,
authorization, ์ธ์ฆ์..)๋ฅผ ํฌํจํ๋ ์์ฒญ
2)์ ๊ฐ์ ์ฌ์ ์์ฒญ(preflight request)์ ๋ณด๋ธ๋ค.
์ด๋ ์ฌ์ ์์ฒญ-์๋ต ํค๋ ํ๋๊ฐ ์ถ๊ฐ๋๋ค.
๊ณผ์
preflight)๋ก ์ด ์์ฒญ์ ๋ณด๋ด๋ ๋๋์ง ๋ฌผ์ด๋ด. ์ด๋ ํค๋์ ๋ค์ ํญ๋ชฉ์ด ํฌํจ๋์ด์ผ ํจ"Origin" : ํด๋น ์์น์์ ์์ฒญ์ ๋ณด๋ธ๋ค๋ ๋ป
"credentials : include" : ์๊ฒฉ์ฆ๋ช
์ ๋ณด๊ฐ ํฌํจ๋๋ค๋ ๋ป
์๊ฒฉ์ฆ๋ช
์ ๋ณด : ํค๋๋ ์ฟ ํค ๋ฑ
"Access-Control-Allow-Origin" : ํด๋น `Origin`์ ํ๊ฐํ๋ค๋ ๋ป
"Access-Control-Allow-Credentials: true" : ์๊ฒฉ์ฆ๋ช
์ ํ๊ฐํ๋ค๋ ๋ป
์ฃผ์์ฌํญ
์๊ฒฉ์ฆ๋ช ์์ฒญ์ ์๋ต์
Access-Control-Allow-Originํค๋ ๊ฐ์*" ์์ผ๋์นด๋๋ฅผ ์ง์ ํ ์ ์๊ณ , ๋ฐ๋์ ์ถ์ฒ๋ฅผ ์ง์ ํด์ผ ํจ!Access-Control-Expose-Headers : ์น ๋ธ๋ผ์ฐ์ ์ ํด๋ผ์ด์ธํธ ์คํฌ๋ฆฝํธ์ ๋
ธ์ถ๋ ํค๋๋ฅผ ๊ฒฐ์ ํจ
private static final String ALLOWED_METHOD_NAMES = "GET,HEAD,POST,DELETE,TRACE,OPTIONS,PATCH,PUT";
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://{ํ๋ก ํธ public ip}", "http://{๋๋ฉ์ธ}"
, "http://www.{๋๋ฉ์ธ}", "https://{๋๋ฉ์ธ}", "https://www.{๋๋ฉ์ธ}")
.allowedMethods(ALLOWED_METHOD_NAMES.split(","))
.allowCredentials(true)
.exposedHeaders(HttpHeaders.LOCATION)
.exposedHeaders(HttpHeaders.AUTHORIZATION);
}
URL์์์ค๋ฆฌ์ง์ ๊ฒฝ์ฐALLOWED_METHOD_NAMES ์ ํด๋นํ๋ HTTP ๋ฉ์๋์ธ ๊ฒฝ์ฐexposedHeaders ๋ก ํด๋ผ์ด์ธํธ ์คํฌ๋ฆฝํธ์ ๋๊ฒจ์ค ํค๋๋ค์ ์ค์ ํ๋ค!SOP ๋ ๋ฌด์์ด๋ฉฐ, ์ ํ์ํ์ง ์ค๋ช
ํด๋ณด์ธ์.sop๋ same origin policy์ ์ฝ์๋ก, url๋ก ํ์ธ ๊ฐ๋ฅํ Origin์ด ๋ค๋ฅธ ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฑธ ์ ํํ๋ ๋ธ๋ผ์ฐ์ ์ ์ฑ
์
๋๋ค.CORS๋ ๋ฌด์์ด๋ฉฐ, ์ ํ์ํ์ง ์ค๋ช
ํด๋ณด์ธ์.CORS, ์ฆ cross origin resource sharing ์ ํด์ค์ผ ํฉ๋๋ค.SOP์์ ์ ์ธ์ํฌ ์ ์์ต๋๋ค.CORS ์ ๊ทผ์ ์ด ์๋๋ฆฌ์ค๋ค๊ณผ ๊ทธ ๊ณผ์ ๋ค์ ์ค๋ช
ํด๋ณด์ธ์preflight request-response ๋ผ๊ณ ๋ถ๋ฆ
๋๋ค.Options ๋ฉ์๋๋ก ๋ณด๋ด์ง๊ณ , ์ด์ ๋ํ ์๋ฒ์ ์ฌ์ ์๋ต์ ๋ฐ์ต๋๋ค.simple request๋ผ ๋ถ๋ฆ
๋๋ค.์ฌํ ๋ฆฌํ์คํธ๋ ์์ฒญ ๋ฉ์๋๊ฐ GET, ์ผ๋ถ POST, HEAD ๋ฉ์๋ ๋ฑ์ด๊ณ ์์ ํ ํค๋๋ง ๋ค์ด๊ฐ ์์ ์ ํด๋นํฉ๋๋ค.credentials: include ๊ฐ ํฌํจ๋๊ณ ์๊ฒฉ์ฆ๋ช
์์ฒญ์ ํ๊ฐํ๋ค๋ ํค๋ ๊ฐ True๋ก ํฌํจ๋์ด ์์ด์ผ ์ค์ ์์ฒญ์ ๋ณด๋ผ ์ ์์ต๋๋ค.
์ ๋ฆฌ ์ต๊ณ ๋ค์!!