๐Ÿ“Œ CORS๋ž€?

๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ (Cross-Origin Resource Sharing)๋Š” ์ถ”๊ฐ€ HTTP Header๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•œ ์ถœ์ฒ˜์—์„œ ์‹คํ–‰ ์ค‘์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ์„ ํƒํ•œ ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋„๋ก ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ์•Œ๋ ค์ค€๋‹ค.

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋ฆฌ์†Œ์Šค๊ฐ€ ์ž์‹ ์˜ ์ถœ์ฒ˜(๋„๋ฉ”์ธ, ํ”„๋กœํ† ์ฝœ, ํฌํŠธ)์™€ ๋‹ค๋ฅผ ๋•Œ, ๊ต์ฐจ ์ถœ์ฒ˜ HTTP ์š”์ฒญ์„ ์‹คํ–‰ํ•œ๋‹ค.

ex) https://domain-a.com์˜ ํ”„๋ก ํŠธ ์—”๋“œ JavaScript ์ฝ”๋“œ๊ฐ€ XMLHttpRequest๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ https://domain-b.com/data.json์„ ์š”์ฒญํ•˜๋Š” ๊ฒฝ์šฐ ๋ณด์•ˆ ์ƒ์˜ ์ด์œ ๋กœ ๋ธŒ๋ผ์šฐ์ €๋Š” HTTP ์š”์ฒญ์„ ์ œํ•œํ•œ๋‹ค.

  • CORS ์ฒด์ œ๋Š” ๋ธŒ๋ผ์šฐ์ €์™€ ์„œ๋ฒ„ ๊ฐ„์˜ ์•ˆ์ „ํ•œ ๊ต์ฐจ ์ถœ์ฒ˜ ์š”์ฒญ ๋ฐ ๋ฐ์ดํ„ฐ ์ „์†ก์„ ์ง€์›ํ•œ๋‹ค.
  • CORS ํ‘œ์ค€์— ๋งž์ถ˜๋‹ค๋Š” ๊ฒƒ์€ ์„œ๋ฒ„์—์„œ๋„ ์ƒˆ๋กœ์šด ์š”์ฒญ๊ณผ ์‘๋‹ต Header๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผํ•œ๋‹ค.

๐Ÿคฟ DeepDive

CORS ํ‘œ์ค€์€ ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ—ˆ์šฉ๋œ ์ถœ์ฒ˜๋ฅผ ์„œ๋ฒ„์—์„œ ์ƒˆ๋กœ์šด HTTP Header์— ์ถ”๊ฐ€ํ•จ์œผ๋กœ์จ ๋™์ž‘ํ•œ๋‹ค.

๐Ÿ“ฎ Simple Request

HTTP ์š”์ฒญ ๋ฉ”์„œ๋“œ๊ฐ€ GET, POST ์ผ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

  1. ๋‹ค๋ฅธ ์ถœ์ฒ˜๋ผ๋ฆฌ ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ, ์š”์ฒญ์— Origin์ด๋ผ๋Š” Header๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

    1
    https://loco9939.com:5000
    • Origin์€ ์š”์ฒญํ•˜๋Š” ์ชฝ์˜ Scheme, ๋„๋ฉ”์ธ, ํฌํŠธ๊ฐ€ ๋‹ด๊ฒจ์žˆ๋‹ค.
    • scheme : https
    • ๋„๋ฉ”์ธ : loco9939.com
    • ํฌํŠธ : :5000
  2. ์š”์ฒญ ๋ฐ›์€ ์„œ๋ฒ„๋Š” ์‘๋‹ต Header์— ์ง€์ •๋œ ACAO(Access Control Allow Origin) ์ •๋ณด๋ฅผ ์‹ค์–ด์„œ ๋ณด๋‚ธ๋‹ค.

  3. ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ACAO ์ •๋ณด๊ฐ€ ๋‹ด๊ธด ์‘๋‹ต๊ณผ ์š”์ฒญ์˜ Origin์„ ๋น„๊ตํ•˜์—ฌ ๋™์ผํ•˜๋ฉด ํ—ˆ๋ฝํ•œ๋‹ค.

โœˆ๏ธ Preflight

๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์‚ฌ์ „์š”์ฒญ์„ ๋จผ์ € ๋ณด๋‚ธ ํ›„ ์„œ๋ฒ„์˜ ์‘๋‹ต์„ ๋ณด๊ณ  ์•ˆ์ „ํ•œ์ง€ ํ™•์ธํ•œ ํ›„ ๋ณธ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๋ฐฉ์‹์ด๋‹ค. ๋ณธ ์š”์ฒญ์€ Simple Request ๋ฐฉ์‹๊ณผ ๋™์ผํ•˜๋‹ค.

๐ŸŒˆ CORS ์˜ค๋ฅ˜ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

๐Ÿ”จ ์„œ๋ฒ„ ์ธก

  • ACAO(Access Control Allow Origin) ์„ค์ •ํ•˜๊ธฐ
    • ๊ตฌ์ฒด์ ์ธ ์ถœ์ฒ˜ ๋ช…์‹œํ•˜๊ธฐ
    • Credentials: include ์˜ต์…˜ ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ * ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ CORS ์—๋Ÿฌ๋ฐœ์ƒ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var http = require("http");

const PORT = process.env.PORT || 3000;

var httpServer = http.createServer(function (request, response) {
// Setting up Headers
response.setHeader("Access-Control-Allow-origin", "*"); // ๋ชจ๋“  ์ถœ์ฒ˜(orogin)์„ ํ—ˆ์šฉ
response.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, OPTIONS, PUT, PATCH, DELETE"
); // ๋ชจ๋“  HTTP ๋ฉ”์„œ๋“œ ํ—ˆ์šฉ
response.setHeader("Access-Control-Allow-Credentials", "true"); // ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์— ์ฟ ํ‚ค ์ฃผ๊ณ ๋ฐ›๊ธฐ ํ—ˆ์šฉ

// ...

response.writeHead(200, { "Content-Type": "text/plain" });
response.end("ok");
});

httpServer.listen(PORT, () => {
console.log("Server is running at port 3000...");
});

Access-Control-Allow-origin ํ—ค๋” ๊ฐ’์œผ๋กœ * ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋“  Origin์—์„œ ์˜ค๋Š” ์š”์ฒญ์„ ํ—ˆ์šฉํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด๋ฏ€๋กœ ๋‹น์žฅ์€ ํŽธํ•  ์ˆ˜ ์žˆ๊ฒ ์ง€๋งŒ, ๋ฐ”๊ฟ”์„œ ์ƒ๊ฐํ•˜๋ฉด ์ •์ฒด๋„ ๋ชจ๋ฅด๋Š” ์ด์ƒํ•œ ์ถœ์ฒ˜์—์„œ ์˜ค๋Š” ์š”์ฒญ๊นŒ์ง€ ๋ชจ๋‘ ํ—ˆ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณด์•ˆ์€ ๋” ํ—ˆ์ˆ ํ•ด์ง„๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ๊ฐ€๊ธ‰์ ์ด๋ฉด ๊ท€์ฐฎ๋”๋ผ๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ถœ์ฒ˜๋ฅผ ์ง์ ‘ ๋ช…์‹œํ•ด์ฃผ๋„๋ก ํ•˜์ž.

๐Ÿ‘‘ ํด๋ผ์ด์–ธํŠธ ์ธก

  • Proxy ์„ค์ •
    • ๋ธŒ๋ผ์šฐ์ € ์š”์ฒญ์„ Proxy์—์„œ ์„ค์ •ํ•œ ์ฃผ์†Œ๋กœ ์šฐํšŒํ•˜์—ฌ ์ „์†กํ•˜๋Š” ๋ฐฉ๋ฒ•
    • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉํ•œ๋‹ค
    • ๊ฐœ๋ฐœ๋‹จ๊ณ„์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๊ณ  Production ํ™˜๊ฒฝ์—์„œ๋Š” Proxy ์ฒ˜๋ฆฌ๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค.