์ ์ : Same-Origin Policy์ ์ฝ์๋ก ๋์ผ ์ถ์ฒ ์ ์ฑ ์ ๋ปํ๋ค. ํ ๋ง๋๋ก โ๊ฐ์ ์ถ์ฒ์ ๋ฆฌ์์ค๋ง ๊ณต์ ๊ฐ ๊ฐ๋ฅํ๋คโ๋ผ๋ ์ ์ฑ !
์ถ์ฒ(Origin) ๊ธฐ์ค :
https://www.codestates.com
vs http://www.codestates.com
https://urclass.codestates.com
vs https://codestates.com
http://codestates.com:81
vs http://codestates.com
ํ์์ฑ : ์ ์ฌ์ ์ผ๋ก ํด๋ก์ธ ์ ์๋ ๋ฌธ์๋ฅผ ๋ถ๋ฆฌํจ์ผ๋ก์จ ๊ณต๊ฒฉ๋ฐ์ ์ ์๋ ๊ฒฝ๋ก๋ฅผ ์ค์ฌ์ค๋ค. ์ฆ, ํดํน ๋ฑ์ ์ํ์์ ๋ณด๋ค ๋ ์์ ํด์ง ์ ์๋ค.
๋ค์ด๋ฒ์ ๋ก๊ทธ์ธํด์ ์๋น์ค๋ฅผ ์ด์ฉํ๊ณ ์๋ค๊ณ ๊ฐ์ ํด๋ณด์.
์๋น์ค ์ด์ฉ์ค์ด ์๋๋๋ผ๋ ๋ก๊ทธ์์์ ๊น๋นกํ๊ฑฐ๋ ์๋ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ผ๋ก ์ธํด ๋ธ๋ผ์ฐ์ ์ ๋ก๊ทธ์ธ ์ ๋ณด๊ฐ ๋จ์์๋ ์ํ์์ ๋์ ๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ๋ ธ๋ฆฌ๋ ์ฝ๋๊ฐ ์๋ ๋ค๋ฅธ ์ฌ์ดํธ์ ๋ฐฉ๋ฌธํ๊ฒ ๋๋ค๋ฉด?
ํด์ปค๋ ๋์ ๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ์ด์ฉํด์ ๋ค์ด๋ฒ์์ ์ฌ์ฉํ ์ ์๋ ๋ชจ๋ ๊ธฐ๋ฅ์ ์ด์ฉํ ์ ์๊ฒ ๋๋ค.
์ด์ SOP์ด ์ค์ํ ๊ฑด ์๊ฒ ๋ค. ๊ทธ๋ฐ๋ฐ...๋ค๋ฅธ ์ถ์ฒ์ ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ๊ฒ ๋ ์ผ์ ๋๋ฌด๋๋ ๋ง๋ค. ๋น์ฅ ๋ก์ปฌ ํ๊ฒฝ์์ ๊ฐ๋ฐ์ ํ ๋๋ ํด๋ผ์ด์ธํธ์ ์๋ฒ๋ฅผ ๋ฐ๋ก ๊ฐ๋ฐํ๋ฉด ์ถ์ฒ๊ฐ ๋ฌ๋ผ์ง๊ฒ ๋๋ค.
์๋ฅผ ๋ค์ด, ์น์ฌ์ดํธ ๊ฐ๋ฐ ์ค์ ๋ค์ด๋ฒ ์ง๋ api๋ฅผ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด? github ์ ๋ณด๋ฅผ ๋ฐ์์์ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด? ๋ชจ๋ ๋ค๋ฅธ ์ถ์ฒ์ ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํด์ผํ๋ ์ผ์ธ๋ฐ, ์ด๋ป๊ฒ ํ๋ฉด ๋ค๋ฅธ ์ถ์ฒ์ ๋ฆฌ์์ค๋ฅผ ๋ฐ์์ฌ ์ ์์๊น?
๋ค๋ฅธ ์ถ์ฒ์ ๋ฆฌ์์ค๋ฅผ ๊ฐ์ ธ์ค๋ ค๊ณ ํ์ง๋ง SOP ๋๋ฌธ์ ์ ๊ทผ์ด ๋ถ๊ฐ๋ฅํฉ๋๋ค. CORS ์ค์ ์ ํตํด ์๋ฒ์ ์๋ต ํค๋์ โAccess-Control-Allow-Originโ์ ์์ฑํ๋ฉด ์ ๊ทผ ๊ถํ์ ์ป์ ์ ์์ต๋๋ค. ๋ผ๋ ์๋ฌ์ด๋ค. ์์ ๊ฐ์ ์๋ฌ๋ CORS๋ก ํด๊ฒฐํ ์ ์๋ค!
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");
})
const cors = require("cors");
const app = 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" });
});
์ด ์ธ ๋ค์ํ ๊ฐ๋ฐ ํ๊ฒฝ์์๋, ํค๋์ ๊ฐ์ ์ค์ ํ๋ ๋ฐฉ๋ฒ๋ง ์๋ฉด CORS ์ค์ ์ ํด์ค ์ ์๋ค.
MERN stack์ JavaScript ์ํ๊ณ์์ ์ธ๊ธฐ ์๋ ํ๋ ์์ํฌ์ธ MongoDB, Express, React, Node.js๋ฅผ ์ง์นญํ๋ ๋จ์ด์ด๋ค. ๊ทธ ์ค Express๋ฅผ ์์๋ณด์!
npm install express
// ์๋ต์ผ๋ก 'Hello World!' ๋ฅผ ๋ณด๋ด๋ Express ์๋ฒ
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
// ์์ Node.js ๋ผ์ฐํ
์ฝ๋
const requestHandler = (req, res) => {
if(req.url === '/lower') {
if (req.method === 'GET') {
res.end(data)
} else if (req.method === 'POST') {
req.on('data', (req, res) => {
// do something ...
})
}
}
}
// Express ๋ผ์ฐํ
์ฝ๋
const router = express.Router()
router.get('/lower', (req, res) => {
res.send(data);
})
router.post('/lower', (req, res) => {
// do something
})
๋ฏธ๋ค์จ์ด(Middleware)๋ ๋ง ๊ทธ๋๋ก ํ๋ก์ธ์ค ์ค๊ฐ์ ๊ด์ฌํ์ฌ ํน์ ์ญํ ์ ์ํํ์ฌ ๊ฑฐ์ณ๊ฐ๋ ํจ์์ด๋ค. ๋ํ, ๋ฏธ๋ค์จ์ด๋ ์๋์ฐจ ๊ณต์ฅ์ ๊ณต์ ๊ณผ ๋น์ทํ๋ค!
โก๏ธ ์์ฒญ(Request)์ ํ์ํ ๊ธฐ๋ฅ์ ๋ํ๊ฑฐ๋, ๋ฌธ์ ๊ฐ ๋ฐ๊ฒฌ๋ ๋ถ๋ํ์ ๋ฐ์ผ๋ก ๊ฑท์ด๋ด๋ ์ญํ ์ ํด์ฃผ๋๋ฐ, ์ด๊ฒ์ด Express์ ๊ฐ์ฅ ํฐ ์ฅ์ ์ด๋ค.
Node.js๋ก HTTP ์์ฒญ body๋ฅผ ์ป์ผ๋ ค๋ฉด, Buffer๋ฅผ ์กฐํฉํด์ ๋ค์ ๋ณต์กํ ๋ฐฉ์์ผ๋ก ์ป์ ์ ์์๋ค.
let body = []; request.on('data', (chunk) => { body.push(chunk); }).on('end', () => { body = Buffer.concat(body).toString(); // body ๋ณ์์๋ ๋ฌธ์์ด ํํ๋ก payload๊ฐ ๋ด๊ฒจ์ ธ ์์ต๋๋ค. });
ํ์ง๋ง, Express์์๋
body-parser
๋ฏธ๋ค์จ์ด๋ฅผ ์ด์ฉํด ๊ฐ๋จํ๊ฒ ์ฒ๋ฆฌํ ์ ์๋ค.npm install body-parser
const bodyParser = require('body-parser'); const jsonParser = bodyParser.json(); // ์๋ต app.post('/users', jsonParser, function (req, res) { })
Express v4.16.0 ๋ถํฐ๋ ๋ฏธ๋ค์จ์ด๋ฅผ ๋ฐ๋ก ์ค์นํ์ง ์๊ณ ๋ด์ฅ ๋ฏธ๋ค์จ์ด์ธ
express.json()
์ ์ฌ์ฉํ๋ค!const jsonParser = express.json(); app.post('/api/users', jsonParser, function (req, res) { // ์๋ต })
Node.js HTTP ๋ชจ๋์ ์ด์ฉํ ์ฝ๋์ CORS ํค๋๋ฅผ ๋ถ์ด๋ ค๋ฉด, ์๋ต ๊ฐ์ฒด์ writeHead ๋ฉ์๋๋ฅผ ์ด์ฉํ ์ ์์๋ค. (๊ทธ๋ฆฌ๊ณ ๋ผ์ฐํ ๋ง๋ค ๋งค๋ฒ ํค๋๋ฅผ ๋ฃ์ด์คฌ์ด์ผ ํ๋ค...)
const defaultCorsHeader = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Accept', 'Access-Control-Max-Age': 10 }; // ์๋ต if (req.method === 'OPTIONS') { res.writeHead(201, defaultCorsHeader); res.end() }
Express์์๋ cors ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๋จํ๊ฒ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ค!
npm install cors
// ๋ชจ๋ ์์ฒญ์ ๋ํด CORS ์ ์ฉ const cors = require('cors'); app.use(cors()); // ํน์ ์์ฒญ์ ๋ํด CORS ์ ์ฉ const cors = require('cors') app.get('/products/:id', cors(), function (req, res, next) { res.json({msg: 'This is CORS-enabled for a Single Route'}) })
app.use()
์ฌ์ฉ)const express = require('express'); const app = express(); const myLogger = function (req, res, next) { console.log('LOGGED'); next(); }; app.use(myLogger); app.get('/', function (req, res) { res.send('Hello World!'); }); app.listen(3000);
// ํ ํฐ์ ํตํด ๋ก๊ทธ์ธ ์ฌ๋ถ๋ฅผ ํ์ธํ๋ ๋ฏธ๋ค์จ์ด app.use((req, res, next) => { // ํ ํฐ์ด ์๋์ง ํ์ธ, ์์ผ๋ฉด ๋ฐ์์ค ์ ์์. if(req.headers.token){ req.isLoggedIn = true; next(); } else { res.status(400).send('invalid user') } })
| ์ฐธ๊ณ ์๋ฃ |