반응형
10.5 SNS API 서버 만들기
- GET /post/my router : 내가 올린 포스트를 가져옴
- GET /posts/hastag/:title router : 해시태그 검색 결과를 가져옴
const request = async (req, api) => {
try {
if (!req.session.jwt) { // 세션에 토큰이 없으면
const tokenResult = await axios.post(`${URL}/token`, {
clientSecret: process.env.CLIENT_SECRET,
});
req.session.jwt = tokenResult.data.token; // 세션에 토큰 저장
}
return await axios.get(`${URL}${api}`, {
headers: { authorization: req.session.jwt },
}); // API 요청
} catch (error) {
if (error.response?.status === 419) { // 토큰 만료시 토큰 재발급 받기
delete req.session.jwt;
return request(req, api);
} // 419 외의 다른 에러면
throw error;
}
};
- request 함수는 NodeBird API 에 요청을 보내는 함수 / 자주 재사용되므로 함수로 분리
- 요청의 헤더 origin 값을 localhost:4000 으로 설정
- 토큰 만료시 419 에러 → 토큰을 지우고 request 함수를 재귀적으로 호출해 다시 요청
- localhost:4000/search/노드
- 노드 해시태그를 사용한 글들을 보여줌
10.6 사용량 제한 구현하기
- 인증된 사용자라고 해도 과도하게 API 를 사용하면 API 서버에 무리
- 일정 기간 내 API를 사용할 수 있는 횟수를 제한해 서버의 트래픽을 줄이는 것이 좋음
- $ npm i express-rate-limit
- 사용량을 제한하는 기능을 가진 npm 패키지
- verifyToken 미들웨어 아래 apiLimiter 미들웨어와 deprecated 미들웨어를 추가
// nodebird-api/middlewares/index.js
exports.apiLimiter = rateLimit({
windowMs: 60 * 1000, // 1분
max: 10,
handler(req, res) {
res.status(this.statusCode).json({
code: this.statusCode, // 기본값 429
message: '1분에 열 번만 요청할 수 있습니다.',
});
},
});
exports.deprecated = (req, res) => {
res.status(410).json({
code: 410,
message: '새로운 버전이 나왔습니다. 새로운 버전을 사용하세요.',
});
};
- apiLimiter 미들웨어를 라우터에 넣으면 옵션으로는 windoMS (기준 시간), max(허용 횟수), handler(제한 초과 시 콜백 함수) 등이 있음
- 현재 설정은 1 분에 한 번 호출 가능하게 되어 있으며, 사용량 제한을 초과하면 429 상태 코드와 함께 허용량을 초과했다는 응답을 전송
- deprecated 미들웨어는 사용하면 안 되는 라우터에 붙여줌
- 410 코드와 함께 새로운 버전을 사용하라는 메시지 응답
- API 응답 목록
- 200 : JSON 데이터
- 401 : 유효하지 않은 토큰
- 410 : 새로운 버전이 나왔음. 새로운 버전 사용
- 419 : 토큰 만료
- 429 : 1분에 한 번만 요청 가능
- 500~ : 기타 서버 에러
10.7 CORS 이해하기
- CORS(Cross-Origin Resource Sharing)
- 실제 서비스에서는 서버에서 사용하는 비밀 키와 프런트에서 사용하는 비밀 키를 따로 두는 게 좋다. 보통 서버에서 사용하는 비밀 키가 더 강력하기 때문
- 프런트에서 사용하는 비밀 키는 모든 사람에게 노출된다는 단점도 존재 → 따라서 데이터베이스에서 clientSecret 외에 frontSecret 같은 컬럼을 추가해 따로 관리하는 것을 권장
🚨 CORS 문제
- Access-Control-Allow-Origin 이라는 헤더가 없다는 내용의 에러!
- 브라우저와 서버의 도메인이 일치하지 않으면 기본적으로 요청이 차단됨
- 브라우저 → 서버 요청일 때 이 현상 발생
- 서버 → 서버 일 때는 발생하지 않음
- 현재 콘솔에서 보이듯이 요청을 보내는 클라이언트 (localhost:4000) 와 요청을 받는 서버 (localhost:8002) 의 도메인이 다르다. → CORS 문제
CORS 문제 해결
- CORS 문제를 해결하려면 응답 헤더에 Access-Control-Allow-Origin 이라는 헤더를 넣어야 함
- 이 헤더는 클라이언트 도메인의 요청을 허락하겠다는 의미
- 응답 헤더를 조작하려면 NodeCat이 아니라 NodeBird API 서버에서 바꿔야
- 왜?
- 응답은 API 서버에서 보내는 거기 때문
- res.set 메서드로 직접 넣어도 되지만, npm 에 편한 패키지 cors 가 있음
- $ npm i cors
CORS 옵션
- credentials: true
- 이 옵션 활성 → 다른 도메인 간에 쿠키 공유 가능
- 프런트와 서버의 도메인이 다른 경우에는 이 옵션 활성 안 하면 로그인이 되지 않을 수 있음
- withCredentials: true
- axios 에서도 도메인이 다른데, 쿠키를 공유해야 하는 경우 이 옵션 활성해야함
- Access-Control-Allow-Origin: *
-
- 표시는 모든 클라이언트의 요청을 허용한다는 뜻
- credentials: true 옵션은 이 헤더를 true 로 만듦
-
QUIZ
❓ Access-Control-Allow-Origin 가 true 가 된 덕에 새로운 문제가 생겼다. 요청을 보내는 주체가 클라이언트라 비밀 키(process.env.CLIENT_SECRET) 가 모두에게 노출된다. 이 문제를 해결하기 위해 할 수 있는 방법으로 옳은 것은?
- 필요한 때에만 옵션을 허용했다가 말았다 한다.
- 처음 비밀 키 발급 시 허용한 도메인을 적게 한다.
- 견딘다.
- * 표시를 작성하지 않고, 모든 클라이언트가 아닌 일부의 요청만을 허락한다.
ANSWER
2번! 호스트와 비밀 키가 모두 일치할 때만 CORS 를 허용하게 수정하면 된다.
가장 많이 나온 오답! 3.견딘다... 견디는 동아리 WINK...
➕ 프록시 서버
- CORS 문제를 해결하는 다른 방법으로는 프록시(대리인) 서버를 사용하는 것이 있음
- 서버 → 서버 요청 때 CORS 문제가 발생하지 않는다는 것을 이용한 방법
10.8 프로젝트 마무리하기
- API 는 다른 애플리케이션의 기능을 사용할 수 있게 해주는 창구
- 현재 NodeCat 이 NodeBird 의 API 를 사용하고 있음
- 모바일 서버를 구성할 때 서버를 REST API 방식으로 구현하면 됨
- API 사용자가 API 를 쉽게 사용할 수 있도록 사용 방법, 요청 형식, 응답 내용에 관한 문서를 준비하자
- JWT 토큰의 내용은 공개되며 변조할 수 있다는 점을 기억하자
- 단 시그니처를 확인하면 변조되었는지 체크할 수 있음
- 토큰을 사용해 API 의 오남용을 막을 수 있음 → 요청 헤더에 토큰이 있는지를 항상 확인하는 것이 좋음
- app.use 외에도 router.us 를 활용해 라우터 간에 공통되는 로직을 처리할 수 있음
- cors 나 passport.authenticate 처럼 미들웨어 내에서 미들웨어를 실행할 수 있음
- 미들웨어를 선택적으로 적용하거나 커스터마이징할 때 이 기법을 사용
- 브라우저와 서버의 도메인이 다르면 요청이 거절된다는 특성(CORS)을 이해하자
- 서버와 서버 간의 요청에서는 CORS 문제가 발생하지 않는다
10.9 진짜 마무리하기
작고 귀여운 페이지를 만들 수 있었던 유익한 시간이 되었습니다!!
우여곡절 끝에 만든 페이지이에요... 오타 질문까지 받아주신 스터디장 님과 그리고 독점했던 Node.js 교과서 무한한 감사와 영광 돌립니다...
+ 실시간으로 발표 응원해준 연진 언니에게도 감사 완전 드립니다
반응형
'WINK-(Web & App) > Express.js (Node.js) 스터디' 카테고리의 다른 글
[2024 JS 심화 백엔드 스터디] 이지원 #1주차 (0) | 2024.04.08 |
---|---|
[2024 JS 심화 백엔드 스터디] 김민서 #1주차 "JS 기본 (1)" (0) | 2024.04.08 |
[2023 백엔드 스터디] 성정규 #1주차 - 3장, 노드 기능 알아보기 (1) | 2023.05.04 |
[2023 백엔드 스터디] 성정규 #1주차 - 2장, 알아두어야 할 자바스크립트 (1) | 2023.05.04 |
[2023 백엔드 스터디] 성정규 #1주차 - 1장.노드 시작하기 (0) | 2023.05.04 |