[๐Ÿ’ป ์ฝ”๋“œ์Šคํ…Œ์ด์ธ  FE 44๊ธฐ] SOP, CORS

JiEunยท2023๋…„ 4์›” 4์ผ
0
post-thumbnail

โœ”๏ธ ์‹œ์ž‘

SOP๊ฐ€ ๋ฌด์—‡์ด๊ณ  ์™œ ์ƒ๊ฒผ๋Š”์ง€, SOP์˜ ๋ฐ˜๋Œ€์ธ CORS์˜ ์—ญํ• ์ด ๋ฌด์—‡์ด๊ณ  ์–ด๋–ป๊ฒŒ ์„ค์ •ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ํ•™์Šตํ–ˆ๋‹ค.


๐Ÿ“์•Œ๊ฒŒ๋œ ๋ถ€๋ถ„

โœ”๏ธ SOP(Same-Origin Policy)

  • ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…
  • ๊ฐ™์€ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋งŒ ๊ณต์œ ๊ฐ€ ๊ฐ€๋Šฅ

ex) http://www.jieun.com:443/name
์ถœ์ฒ˜(origin) : http://www.jieun.com:443/name
ํ”„๋กœํ† ์ฝœ : http
ํฌํŠธ : 443

  • ์ถœ์ฒ˜๋Š” ํ”„๋กœํ† ์ฝœ, ํ˜ธ์ŠคํŠธ, ํฌํŠธ์˜ ์กฐํ•ฉ์„ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.
  • ์ด์ค‘ ํ•˜๋‚˜๋ผ๋„ ๋‹ค๋ฅด๋ฉด ๋™์ผํ•œ ์ถœ์ฒ˜๋กœ ๋ณด์ง€ ์•Š๋Š”๋‹ค.

SOP๊ฐ€ ์ƒ๊ธด ์ด์œ 

  • ํ•ด๋กœ์šด ๋ฌธ์„œ๋ฅผ ๋ถ„๋ฆฌํ•จ์œผ๋กœ ๊ณต๊ฒฉ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ๋กœ๋ฅผ ์ค„์—ฌ์ค€๋‹ค.
  • ์‚ฌ์ดํŠธ์™€์˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ ๋ฅผ ์ œํ•œํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ์ธ ์ •๋ณด๊ฐ€ ํƒ€ ์‚ฌ์ดํŠธ์˜ ์ฝ”๋“œ์— ์˜ํ•ด์„œ ์ƒˆ์–ด๋‚˜๊ฐ€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ (๊ฐœ์ธ ์ •๋ณด ์œ ์ถœ ๋ฐฉ์ง€)

SOP์œผ๋กœ ์ธํ•ด ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐ›์•„ ์˜ฌ ์ˆ˜ ์—†๊ฒŒ ๋˜์—ˆ๋Š”๋ฐ ๋งŒ์•ฝ ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐ›์•„์™€์•ผํ•˜๋Š” ์ƒํ™ฉ์ด ์˜จ๋‹ค๋ฉด? (์™ธ๋ถ€ API ๋“ฑ)

โœ”๏ธ CORS(Cross-Origin Resoure)

  • ๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ 
  • SOP์— ์˜ํ•ด ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ ๋ฅผ ๋ง‰์ง€๋งŒ CORS๋ฅผ ์‚ฌ์šฉํ•ด ์ ‘๊ทผ ๊ถŒํ•œ(๋‹ค๋ฅธ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ  ๊ถŒํ•œ)์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

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

1. ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ(Preflight Request)

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

ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ โžก๏ธŽ [์š”์ฒญ] โžก๏ธŽ Access-Control-Allow-Origin โžก๏ธŽ [์‘๋‹ต] โžก๏ธŽ ์‹ค์ œ์š”์ฒญ ๋ณด๋‚ด๊ธฐ

ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ๊ฐ€ ํ•„์š”ํ•œ ์ด์œ 

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

CORS์— ๋Œ€๋น„๊ฐ€ ๋˜์–ด์žˆ์ง€ ์•Š๋Š” ์„œ๋ฒ„๋ผ๋„ ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ์„ ๋จผ์ € ๋ณด๋‚ด๊ฒŒ ๋˜๋ฉด, ํ”„๋ฆฌํ”Œ๋ฆฌ์•„ํŠธ ์š”์ฒญ์—์„œ CORS ์—๋Ÿฌ๋ฅผ ๋„์šฐ๊ฒŒ ๋œ๋‹ค.
CORS ๊ธฐ๋ณธ ์‚ฌ์–‘ : ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ

2. ๋‹จ์ˆœ ์š”์ฒญ(Simple Request)

  • ํŠน์ • ์กฐ๊ฑด์ด ๋งŒ์กฑ๋˜๋ฉด ํ”„๋ฆฌํ”Œ๋ผ์ดํŠธ ์š”์ฒญ์„ ์ƒ๋žตํ•˜๊ณ  ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

3. ์ธ์ฆ ์ •๋ณด๋ฅผ ํฌํ•จํ•œ ์š”์ฒญ(Creadentialed Request)

  • ์š”์ฒญ ํ—ค๋”์— ์ •๋ณด๋ฅผ ๋‹ด์•„ ๋ณด๋‚ด๋Š” ์š”์ฒญ
  • ์ถœ์ฒ˜๊ฐ€ ๋‹ค๋ฅผ ๊ฒฝ์šฐ ๋ณ„๋„์˜ ์„ค์ •์„ ํ•˜์ง€ ์•Š์œผ๋ฉด ์ฟ ํ‚ค๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์—†๋‹ค.
  • ํ”„๋ก ํŠธ ์ธก์—์„œ ์š”์ฒญ ํ—ค๋”: withCredentials: ture
  • ์„œ๋ฒ„์ธก์—์„œ ์‘๋‹ต ํ—ค๋” : Access-Controll-Allow-Credentials:true
  • ์„œ๋ฒ„ ์ธก์—์„œ Access-Control-Allow-Origin์„ ์„ค์ • ํ•  ๋•Œ ๋ชจ๋“  ์ถœ์ฒ˜๋ฅผ ํ—ˆ์šฉํ•œ๋‹ค๋Š” ๋œป์˜ ์™€์ผ๋“œ ์นด๋“œ(*)๋กœ ์„ค์ •ํ•ด ์ค˜์•ผ ํ•œ๋‹ค.

โœ”๏ธ CORS ์„ค์ • ๋ฐฉ๋ฒ•

1.Node.js ์„œ๋ฒ„

  • Node.js๋กœ ๊ฐ„๋‹จํ•œ HTTP ์„œ๋ฒ„๋ฅผ ๋งŒ๋“  ๊ฒฝ์šฐ ์‘๋‹ต ํ—ค๋”๋ฅผ ์„ค์ •ํ•ด ์ค„ ์ˆ˜ ์žˆ๋‹ค.
const http = require ("http");
const server = http.createServer((request, response) => {
	//1. ๋ชจ๋“  ๋„๋ฉ”์ธ
  	response.setHeader("Access-Control-Allow-Origin", "*");
  
	//2. ํŠน์ • ๋„๋ฉ”์ธ
	response.setHeader("Access-Control-Allow-Origin", "http://Jieun.com")
  
  	//3. ์ธ์ฆ ์ •๋ณด๋ฅผ ํฌํ•จํ•œ ์š”์ฒญ์„ ๋ฐ›์„ ๊ฒฝ์šฐ
  	response.setHeader("Access-Control-Allow-Origin", "true")	
});

2. Express ์„œ๋ฒ„

  • Express ํ”„๋ ˆ์ž„ ์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์„œ๋ฒ„๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒฝ์šฐ CORS ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•ด ๋”์šด ๊ฐ„๋‹จํ•˜๊ฒŒ CORS ์„ค์ •์„ ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.
const cors = require("cors");
const app = express();
// 1. ๋ชจ๋“  ๋„๋ฉ”์ธ
app.use(cors());

// 2. ํŠน์ • ๋„๋ฉ”์ธ
const options = {
	origin: "http://Jieun.com", // ์ ‘๊ทผ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š” ๋„๋ฉ”์ธ
  	credentials: true, // ์‘๋‹ต ํ—ค๋”์— Access-Controll-Allow-Credentials ์ถ”๊ฐ€
  	optionsSuccessStates: 200, // ์‘๋‹ต ์ƒํƒœ๋ฅผ 200์œผ๋กœ ์„ค์ •
};
app.use(cors(options));

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

๋‹ค์–‘ํ•œ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋„ ํ—ค๋”์˜ ๊ฐ’์„ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•๋งŒ ์•Œ๋ฉด CORS ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

Node Server

- ์„œ๋ฒ„ ์‹คํ–‰

node server/ํŒŒ์ผ ๊ฒฝ๋กœ
  • ์„œ๋ฒ„ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ • ํ›„ ์ €์žฅํ•œ ๊ฒฝ์šฐ ํ”„๋กœ๊ทธ๋žจ์„ ๋งค๋ฒˆ ๋‹ค์‹œ ์‹คํ–‰ํ•ด ์ค˜์•ผํ•œ๋‹ค.

- npx nodemon์œผ๋กœ ํŒŒ์ผ ์‹คํ–‰

npx nodemon server/ํŒŒ์ผ ๊ฒฝ๋กœ

- ํด๋ผ์ด์–ธํŠธ ์‹คํ–‰

npx serve -l ํฌํŠธ๋ฒˆํ˜ธ client/

HTTP ํŠธ๋žœ์žญ์…˜ ํ•ด๋ถ€ ๋ฐ”๋กœ๊ฐ€๊ธฐ


โœ๏ธ ๋งˆ์น˜๋ฉฐ

๊ณผ์ œ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ๋ถ„๋ช… ๋งž๊ฒŒ ์ˆ˜์ •ํ•˜๊ณ  ์ €์žฅ๊นŒ์ง€ ํ–ˆ๋Š”๋ฐ syntaxerr๊ฐ€ ๋‚˜์„œ ์• ๋ฅผ ๋จน์—ˆ๋‹ค.
์•Œ๊ณ  ๋ณด๋‹ˆ ์„œ๋ฒ„ ์ฝ”๋“œ๋Š” ์ˆ˜์ • ํ›„ ์ €์žฅํ–ˆ์„ ๋Œ€ ํ”„๋กœ๊ทธ๋žจ์„ ๋งค๋ฒˆ ๋‹ค์‹œ ์‹คํ–‰ํ•ด ์ค˜์•ผํ•œ๋‹ค.

์ฆ‰, ์„œ๋ฒ„ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ–ˆ์„ ๋•Œ ํ•ด๋‹น ๊ฒฝ๋กœ ํ„ฐ๋ฏธ๋„์— node server/ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ๋งค๋ฒˆ ์‹คํ–‰ํ•ด ์ฃผ๋ฉด ํ•ด๊ฒฐ๋œ๋‹ค.

๋„ˆ๋ฌด ์–ด๋ ต๊ฒŒ ์ƒ๊ฐํ•ด์„œ ์‹œ๊ฐ„์„ ์žก์•˜๋˜ ๊ฑฐ ๊ฐ™๋‹ค.

profile
๐Ÿ’ป ํ”„๋ก ํŠธ์—”๋“œ๋ฅผ ๋ชฉํ‘œ๋กœ ์„ฑ์žฅ ์ค‘! (์•Œ์•„๋ดค๋˜ ๋‚ด์šฉ ๋“ฑ์„ ์ •๋ฆฌํ•˜๊ธฐ)

0๊ฐœ์˜ ๋Œ“๊ธ€