roqkf

[Web Server] CORS ๋ณธ๋ฌธ

๐Ÿ’ป Development/Web

[Web Server] CORS

ahyeon7 2022. 12. 11. 21:41

SOP

Same-Origin Policy์˜ ์•ฝ์ž๋กœ, ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์„ ์˜๋ฏธํ•œ๋‹ค. ์ฆ‰, ๊ฐ™์€ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋งŒ์ด ๊ณต์œ ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์ •์ฑ…์ด๋‹ค. ์—ฌ๊ธฐ์„œ์˜ ์ถœ์ฒ˜๋Š” ํ”„๋กœํ† ์ฝœ/ ํ˜ธ์ŠคํŠธ/ ํฌํŠธ์˜ ์กฐํ•ฉ์œผ๋กœ ์ด ์กฐํ•ฉ ์ค‘ ํ•˜๋‚˜๋ผ๋„ ๋‹ค๋ฅด๋‹ค๋ฉด ๋™์ผํ•œ ์ถœ์ฒ˜๋กœ ๋ณด์ง€ ์•Š๋Š”๋‹ค.

https://www.naver.com vs http://www.naver.com
[https / http] ๋‘ URI๋Š” ํ”„๋กœํ† ์ฝœ์ด ๋‹ค๋ฅด๋ฏ€๋กœ ๋™์ผํ•œ ์ถœ์ฒ˜๊ฐ€ ์•„๋‹˜

๐Ÿค” SOP ์ƒ๊ฒจ๋‚œ ์ด์œ 

  • ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์€ ์ž ์žฌ์ ์œผ๋กœ ํ•ด๋กœ์šธ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์„œ๋ฅผ ๋ถ„๋ฆฌํ•˜๋ฏ€๋กœ์จ ๊ณต๊ฒฉ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ๋กœ๋ฅผ ์ค„์—ฌ ์ค€๋‹ค. ์ฆ‰, SOP์„ ํ†ตํ•ด ํ•ดํ‚น์˜ ์œ„ํ˜‘์—์„œ ์•ˆ์ „ํ•ด์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋งŒ์•ฝ ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์ด ์—†๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด ๋„ค์ด๋ฒ„ ๊ฐ™์€ ์›น ํŽ˜์ด์ง€์— ๋กœ๊ทธ์ธํ•ด์„œ ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด, ์„œ๋น„์Šค ์ด์šฉ ์ค‘์ด ์•„๋‹ˆ๋”๋ผ๋„ ๋กœ๊ทธ์•„์›ƒ์„ ๊นœ๋นกํ•˜๊ฑฐ๋‚˜ ์ž๋™ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ์œผ๋กœ ์ธํ•ด์„œ ๋ธŒ๋ผ์šฐ์ €์— ๋กœ๊ทธ์ธ ์ •๋ณด๊ฐ€ ๋‚จ์•„์žˆ์„ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ƒํƒœ์—์„œ ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ๋…ธ๋ฆฌ๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ๋Š” ๋‹ค๋ฅธ ์‚ฌ์ดํŠธ๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ๋‚˜์˜ ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ์ด์šฉํ•ด์„œ ํ•ด์ปค๊ฐ€ ์ด์™€ ๊ด€๋ จ๋œ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค. SOP์ด ์žˆ๋‹ค๋ฉด ์• ์ดˆ์— ๋‹ค๋ฅธ ์‚ฌ์ดํŠธ์™€์˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ ๋ฅผ ์ œํ•œํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋กœ๊ทธ์ธ์˜ ์ •๋ณด๊ฐ€ ๋‹ค๋ฅธ ์‚ฌ์ดํŠธ๋กœ ์ƒˆ์–ด๋‚˜๊ฐ€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋  ์ผ์ด ๋ฌด์ˆ˜ํžˆ ๋งŽ์€๋ฐ ์ด ๋ฆฌ์†Œ์Šค๋“ค์„ ์–ด๋–ป๊ฒŒ ๋ฐ›์•„ ์˜ฌ ์ˆ˜ ์žˆ์„๊นŒ?

CORS

Cross-Origin Resource Sharing์˜ ์•ฝ์ž๋กœ, ๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ์ถ”๊ฐ€ HTTP ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•œ ์ถœ์ฒ˜์—์„œ ์‹คํ–‰ ์ค‘์ธ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ์„ ํƒํ•œ ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋„๋ก ๋ธŒ๋ผ์šฐ์ €์— ์•Œ๋ ค์ฃผ๋Š” ์ฒด์ œ์ด๋‹ค. CORS๊ฐ€ ์—†๋‹ค๋ฉด ๋„ค์ด๋ฒ„์—์„œ ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ์‚ฌ์ดํŠธ๋กœ ์ด๋™ํ•˜๊ฒŒ ๋  ๋•Œ ๊ธฐ๋ณธ์ ์œผ๋กœ SOP์— ์˜ํ•ด์„œ ๋ฆฌ์†Œ์Šค ๊ณต์œ ๊ฐ€ ๋ง‰ํžˆ์ง€๋งŒ CORS๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ ‘๊ทผ ๊ถŒํ•œ์„ ์–ป๊ฒŒ ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

  • ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๊ณ  ํ–ˆ์ง€๋งŒ SOP ๋•Œ๋ฌธ์— ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
    CORS ์„ค์ •์„ ํ†ตํ•ด ์„œ๋ฒ„์˜ ์‘๋‹ต ํ—ค๋”์— ‘Access-Control-Allow-Origin’์„ ์ž‘์„ฑํ•˜๋ฉด ์ ‘๊ทผ ๊ถŒํ•œ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

CORS ๋™์ž‘ ๋ฐฉ์‹

  1. ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ (Preflight Request)
  • ์ ‘๊ทผ ๊ถŒํ•œ ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์ „, OPTIONS ๋ฉ”์„œ๋“œ๋กœ ์‚ฌ์ „ ์š”์ฒญ์„ ๋ณด๋‚ด ํ•ด๋‹น ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผ ๊ถŒํ•œ์ด ์žˆ๋Š”์ง€๋ถ€ํ„ฐ ํ™•์ธํ•˜๋Š” ๊ฒƒ


์œ„ ์ด๋ฏธ์ง€์˜ ํ๋ฆ„๊ณผ ๊ฐ™์ด, ๋ธŒ๋ผ์šฐ์ €๋Š” ์„œ๋ฒ„์— ์‹ค์ œ ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์ „์— ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ , ์‘๋‹ต ํ—ค๋”์˜ Access-Control-Allow-Origin์œผ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ธ ์ถœ์ฒ˜๊ฐ€ ๋Œ์•„์˜ค๋ฉด ์‹ค์ œ ์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋œ๋‹ค.

๋งŒ์•ฝ์— ์š”์ฒญ์„ ๋ณด๋‚ธ ์ถœ์ฒ˜๊ฐ€ ์ ‘๊ทผ ๊ถŒํ•œ์ด ์—†๋‹ค๋ฉด ๋ธŒ๋ผ์šฐ์ €์—์„œ CORS ์—๋Ÿฌ๋ฅผ ๋„์šฐ๊ฒŒ ๋˜๊ณ , ์‹ค์ œ ์š”์ฒญ์€ ์ „๋‹ฌ๋˜์ง€ ์•Š๋Š”๋‹ค.

๐Ÿค” ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ์€ ์™œ ํ•„์š”ํ•œ ๊ฑธ๊นŒ?

  • ์‹ค์ œ ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์ „์— ๋ฏธ๋ฆฌ ๊ถŒํ•œ ํ™•์ธ์„ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์‹ค์ œ ์š”์ฒญ์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ํ†ต์งธ๋กœ ๋ณด๋‚ด๋Š” ๊ฒƒ๋ณด๋‹ค ๋ฆฌ์†Œ์Šค ์ธก๋ฉด์—์„œ ํšจ์œจ์ 
  • CORS์— ๋Œ€๋น„๊ฐ€ ๋˜์–ด์žˆ์ง€ ์•Š์€ ์„œ๋ฒ„๋ฅผ ๋ณดํ˜ธํ•  ์ˆ˜ ์žˆ๋‹ค. CORS ์ด์ „์— ๋งŒ๋“ค์–ด์ง„ ์„œ๋ฒ„๋“ค์€ SOP ์š”์ฒญ๋งŒ ๋“ค์–ด์˜ค๋Š” ์ƒํ™ฉ์„ ๊ณ ๋ คํ•˜๊ณ  ๋งŒ๋“ค์–ด์กŒ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ์ถœ์ฒ˜์—์„œ ๋“ค์–ด์˜ค๋Š” ์š”์ฒญ์— ๋Œ€ํ•œ ๋Œ€๋น„๊ฐ€ ๋˜์–ด์žˆ์ง€ ์•Š๋‹ค.
  1. ๋‹จ์ˆœ ์š”์ฒญ (Simple Request)
  • ํŠน์ • ์กฐ๊ฑด์ด ๋งŒ์กฑ๋˜๋ฉด ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ์„ ์ƒ๋žตํ•˜๊ณ  ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ฒƒ

๐Ÿ”Ž ์กฐ๊ฑด

๐Ÿ”น GET, HEAD, POST ์š”์ฒญ ์ค‘ ํ•˜๋‚˜
๐Ÿ”น ์ž๋™์œผ๋กœ ์„ค์ •๋˜๋Š” ํ—ค๋” ์™ธ์—, Accept, Accept-Language, Content-Language, Content-Type ํ—ค๋”์˜ ๊ฐ’๋งŒ ์ˆ˜๋™์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. / Content-Type ํ—ค๋”์—๋Š” application/x-www-form-urlencoded, multipart/form-data, text/plain ๊ฐ’๋งŒ ํ—ˆ์šฉ

  1. ์ธ์ฆ์ •๋ณด๋ฅผ ํฌํ•จํ•œ ์š”์ฒญ (Credentialed Request)
  • ์š”์ฒญ ํ—ค๋”์— ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ด์•„ ๋ณด๋‚ด๋Š” ์š”์ฒญ, ๋ณ„๋„์˜ ์„ค์ •์„ ํ•˜์ง€ ์•Š์œผ๋ฉด ์ฟ ํ‚ค๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์—†๋‹ค. ๋ฏผ๊ฐํ•œ ์ •๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด ๊ฒฝ์šฐ ํ”„๋ก ํŠธ, ์„œ๋ฒ„ ์–‘์ธก ๋ชจ๋‘ CORS ์„ค์ •์ด ํ•„์š”

๐Ÿ”น ํ”„๋ก ํŠธ ์ธก ์š”์ฒญ ํ—ค๋”์— withCredentials : true ๋ฅผ ๋„ฃ์–ด์ค˜์•ผ ํ•จ
๐Ÿ”น ์„œ๋ฒ„ ์ธก ์‘๋‹ต ํ—ค๋”์— Access-Control-Allow-Credentials : true ๋ฅผ ๋„ฃ์–ด์ค˜์•ผ ํ•จ
๐Ÿ”น ์„œ๋ฒ„ ์ธก์—์„œ Access-Control-Allow-Origin ์„ ์„ค์ •ํ•  ๋•Œ, ๋ชจ๋“  ์ถœ์ฒ˜๋ฅผ ํ—ˆ์šฉํ•œ๋‹ค๋Š” ๋œป์˜ ์™€์ผ๋“œ์นด๋“œ(*)๋กœ ์„ค์ •ํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ค๋ฃจ๋Š” ๋งŒํผ ์ถœ์ฒ˜๋ฅผ ์ •ํ™•ํ•˜๊ฒŒ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค.

CORS ์„ค์ • ๋ฐฉ๋ฒ•

  1. Node.js ์„œ๋ฒ„
    [Node.js๋กœ ๊ฐ„๋‹จํ•œ HTTP ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค ๊ฒฝ์šฐ] ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‘๋‹ต ํ—ค๋”๋ฅผ ์„ค์ •
const http = require('http');

const server = http.createServer((request, response) => {
// ๋ชจ๋“  ๋„๋ฉ”์ธ
  response.setHeader("Access-Control-Allow-Origin", "*");

// ํŠน์ • ๋„๋ฉ”์ธ
  response.setHeader("Access-Control-Allow-Origin", "https://codestates.com");

// ์ธ์ฆ ์ •๋ณด๋ฅผ ํฌํ•จํ•œ ์š”์ฒญ์„ ๋ฐ›์„ ๊ฒฝ์šฐ
  response.setHeader("Access-Control-Allow-Credentials", "true");
})
  1. Express ์„œ๋ฒ„
    [Express ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์„œ๋ฒ„๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒฝ์šฐ] cors ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ณด๋‹ค ๋” ๊ฐ„๋‹จํ•˜๊ฒŒ CORS ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
const cors = require("cors");
const app = express(); // express ํ”„๋ ˆ์ž„ ์›Œํฌ ์‚ฌ์šฉ

//๋ชจ๋“  ๋„๋ฉ”์ธ
app.use(cors());

//ํŠน์ • ๋„๋ฉ”์ธ
const options = {
  origin: "https://codestates.com", // ์ ‘๊ทผ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š” ๋„๋ฉ”์ธ
  credentials: true, // ์‘๋‹ต ํ—ค๋”์— Access-Control-Allow-Credentials ์ถ”๊ฐ€
  optionsSuccessStatus: 200, // ์‘๋‹ต ์ƒํƒœ 200์œผ๋กœ ์„ค์ •
};

app.use(cors(options));

//ํŠน์ • ์š”์ฒญ
app.get("/example/:id", cors(), function (req, res, next) {
  res.json({ msg: "example" });
});

'๐Ÿ’ป Development > Web' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

JSON  (0) 2022.12.16
[Web Server] Refactor Express  (0) 2022.12.16
REST API  (0) 2022.12.11
[Web] HTTP  (0) 2022.12.11
[Web] ๋ธŒ๋ผ์šฐ์ € ์ž‘๋™ ์›๋ฆฌ  (0) 2022.12.11