🐈오늘 공부한 것
✔️CORS 와 SOP
CORS 란 Cross-Origin Resource Sharing 의 약자로, "교차 출처 리소스 공유" 를 의미한다. 웹 사이트간 (서로 다른 출처의) 리소스를 교환하는 것을 방지하는 SOP Same-Origin Policy 라는 것이 있는데, 서로 리소스를 공유하기 위한 권한이 CORS 라고 할 수 있다. 외부 API 를 이용하는 것 또한 다른 출처끼리 리소스를 공유하는 것이기 때문에 CORS 로 권한을 주어야 하는데, HTTP 헤더에 Access-Control-Allow-Origin을 추가해 다른 출처의 선택한 리소스에 접근할 수 있도록 권한을 부여하고, 이런 권한이 있다는 것을 브라우저에 알려주는 역할을 한다.
CORS 의 동작 방식으로는 크게 1. 프리플라이트 요청 / 2. 단순 요청 / 3. 인증정보 포함 요청 세가지 종류가 있다.
✔️Preflight 요청
실제 요청을 보내기 전에 클라이언트에서 OPTION 메서드로 사전 요청을 보내서 해당 리소스에 접근할 권한이 있는지를 미리 확인하는 것이다. 처음부터 데이터 전체를 가지고 요청을 보내는 것 보다 미리 권한이 있음을 확인하고 실제 요청을 보내는 방식이라서, CORS에 대비가 되어 있지 않은 서버를 보호할 수도 있다. 실제 요청을 보냈는데 CORS에 대비가 안된 서버인 경우에는 요청을 처리한다음에 응답을 보내면서 CORS 에러가 발생하기 때문에 의도치 않은 동작을 할 수도 있다. 이런 측면 때문에 프리플라이트 요청이 CORS의 기본 사양이 되었다.
✔️node.js http 모듈과 웹서버
오늘 과제는 http 모듈을 사용해서 node.js http 웹서버를 구현하는 것이었다. 처음부터 모든 내용을 구현하진 않았지만 http 모듈이 낯설고 모르는 용어가 많이 등장하다보니... 완벽하게 이해는 못했고 오늘 공부한 내용까지만이라도 정리해보려고 한다.🥲일단 오늘의 참고 자료는 Node.js 공식문서 중 HTTP 트랜잭션 해부 라는 챕터이다.
1. 일단... node.js에서 http 웹서버를 구축하기 위해서 http 모듈이라는 것을 사용할 수 있다. 서버를 구현하기 위해서 express 모듈을 사용할 수도 있다고 하는데, http 모듈은 express 보다 좀 더 직접 설정해야 하는 부분이 많은 것 같다. express 에서는 CORS 미들웨어를 사용한다고 한다.
2. http 모듈에서는 server 객체라는 것을 createServer() 메서드로 생성할 수 있다. 이 createServer 메서드에 함수를 전달해서 특정 port 로 요청이 들어왔을 때 함수 내의 로직이 이 요청에 대한 응답을 하도록 만들 수 있다. server 객체에 listen 이라는 메서드를 달아서 서버를 실행할 수 있다.
3. createServer 메서드에 전달된 함수는 첫번째 인자로 request 객체를, 두번째 인자로 response 객체를 받을 수 있다. request 객체에는 요청에 대한 정보가 담겨있고, 이 요청을 파악해 response 객체를 통해서 클라이언트에 보내줄 응답 메시지를 작성하고, 응답을 보내줄 수 있다.
4. request의 body 내용에 접근하기 위해서 .on 메서드로 이벤트를 연결시킬 수 있는데, node.js의 이벤트에 대해서 잘 모른다는 것을 알게되었다...! 그래서 잘 설명하는 것은 좀 힘들 것 같다. 대신 request의 body 에 담긴 내용이 ReadableStream 이라는 데이터 형태로 되어있어서, 이것을 가공할 수 있는 문자열로 만들기 위한 과정을 거친다는 것은 이해했다.
오늘 과제는 먼저 OPTIONS 메서드로 들어온 프리플라이트 요청에 적절한 응답을 해주고, 그 뒤에 이어서 들어오는 POST 요청 중 두 가지 다른 종류의 엔드포인트에 맞게 적절한 응답을 보내주는 HTTP 웹서버를 구축하는 것이 목표였다. 처음에 if문을 두 번 사용해서 request.method 가 OPTIONS 인 경우와 POST 인 경우를 분기시켜서 응답을 처리하려고 했는데, 뭔가 잘 되지 않았다. 그래서 각 조건을 else...if 로 분기시키니 잘 작동했다.
+ 그런데 아무래도 같은 POST 요청에서 비슷한 동작을 하면서 엔드포인트에 따라 다르게 동작하는 것이기 때문에, 겹치는 코드를 정리하기 위해서 함수를 만들어서 사용했다. 내가 만든 server 객체의 응답 로직은 아래와 같다.
const server = http.createServer((request, response) => {
const {method, url} = request;
// POST 요청일 경우 적절한 response를 해주는 함수
const responseBody = function (url) {
// 클라이언트의 요청 body에 접근하여 문자열화한다.
let body = [];
request
.on('data', chunk => {
body.push(chunk);
})
.on('end', () => {
body = Buffer.concat(body).toString();
console.log(`http request method is ${method}, url is ${url}`);
response.writeHead(200, defaultCorsHeader);
// 엔드포인트에 따라 분기하여 응답한다.
if (url === '/upper') response.end(body.toUpperCase());
else if (url === '/lower') response.end(body.toLowerCase());
});
};
// 메서드에 따라 다른 응답을 한다.
if (method === 'OPTIONS') {
console.log(`http request method is ${method}, url is ${url}`);
response.writeHead(200, defaultCorsHeader);
response.end();
} else if ((method === 'POST' && url === '/upper') || url === '/lower') {
responseBody(url);
} else {
response.statusCode = 400;
response.end('BAD REQUEST');
}
});
요청 메서드를 확인하는 부분에서, 메서드가 POST 인지만 확인하고 엔드포인트는 확인을 안했더니 다른 엔드포인트로 요청이 들어왔을 때 else 로 넘어가지 않아서 에러핸들링이 되지 않았다. 그래서 일단 엔드포인트를 확인하는 조건까지 추가해주었는데, 만약 엔드포인트가 엄청 많아진다면 어떻게 해야하는거지...라는 고민이 생겼다.🙄
🐈더 공부할 것
1. EventEmitter 와 node.js 이벤트에 대해서 알아보기
2. Buffer 객체와 ReadableStream
3. CORS
🐈오늘의 느낀 점
1.앞으로 다음주 수요일까지 웹서버에 대한 내용을 공부한다. 내일은 express로 오늘 코드를 리팩터링을 하는데, 오늘 내용도 제대로 이해를 못한 것 같은데 괜찮을까...하는 걱정이 앞선다. 서버가 백엔드의 영역이긴 하지만 프론트로 시작해도 결국은 풀스택을 지향해야 한다고 생각하기 때문에 제대로 공부해보고 싶다...!!!
2. 오늘 TIL 스터디 발표모임에서는 props drilling과 선언적 프로그래밍, 프로그래밍에서의 추상화에 대한 내용을 준비해주셨다. 예상은 했지만 현업에서는 개념을 알고있는 것에서 그치지 않고 실제로 얼마나 실천하느냐를 중요하게 보는 것 같다.(당연하게도....)
지금까지는 배운 내용 그대로를 사용하는 것에 초점을 맞추었는데 앞으로는 좋은 코드에 대해 고민하면서 코드를 짜야겠다. 또 다른 사람의 관점에서 코드 리뷰를 받고 고쳐나가는 것도 중요하지만, 그 전에 먼저 내가 내 코드에 대한 확신이 있어야겠다는 생각이 많이 들었다. 나의 관점에서 좋은 코드란 어떤 것인지, 그에 맞춰서 짜려는 노력이 먼저 필요하고 그랬을 때 피드백도 더 효과적으로 받아들이면서 개선할 수 있지 않나...싶다. 결론은 페어프로그래밍을 더 적극적으로 활용해야겠다.
3. 오늘은 오전에 알러지 약을 먹고 하루종일 비몽사몽이었다. 커피를 마셔도 졸음이 가시지 않아서 결국 오전 개인공부도 못했고, 저녁에 스터디 모임에나 겨우 참여했다 ㅜㅜ. 공휴일이 껴 있어서 3일이나 쉬는 것에 감사해야겠다...
'TIL' 카테고리의 다른 글
[Day 38] 2022-0816 (0) | 2022.08.17 |
---|---|
[Day 37] 2022-0812 (0) | 2022.08.13 |
[Day 35] 2022-0810 (0) | 2022.08.10 |
[Day 34] 2022-0809 (0) | 2022.08.09 |
[Day 33] 2022-0808 (0) | 2022.08.08 |