Skip to main content

GDSC 토이프로젝트 개발 노트

📅 22-12-26

📌 로그인 API 구현

  • 어차피 2주차에 JWT 붙이면서 또 수정 들어갈테니 DB 접근만 우선 구현하기로 했다.
  • ChatGPT에게 코드를 내놓으라고 협박했다.
    • ✅ 해당 코드를 읽어보면 대강 이런식으로 하는구나, 하고 감이 빨리 잡힌다.
    • ⚠️ 매번 이러면 안되고 생산성이 우선일 때 추천한다.

ChatGPT result

📌 프리즈마 연결

  • sequelize 쓰려다가 prisma를 추천받음 -> 매우 간결해진 코드
  • mysql로 ORM 없는 쌩 쿼리도 연습 차 작성해보았다.
가독성 끝내주는 쌩쿼리 보기
connection.query(
'INSERT INTO Users (nickname, name, studentId, department, status) values (?, ?, ?, ?, ?);',
[nickname, name, studentId, department, status],
(error, results) => {
if (error) {
console.error(error);
res.status(500).send({error: 'An error occurred while saving..'});
} else {
// Query the database for the name
const query = 'SELECT nickname, name FROM users WHERE name = ?';
connection.query(query, [name], (error, results) => {
if (error) {
console.error(error);
res.sendStatus(500);
} else {
res.send(results);
}
});
}
}
);

📅 23-01-01

📌 Cloud Functions 배포

  • 일반적으로 Functions는 한 개 당 하나의 로직을 의도했다고 한다.
    • 하지만 난 하나의 Functions에 전체 API를 연결했다.
  • CJS에서 ESM으로 변경, 모듈 분리하여 배포
    • ESM으로 갈아탄 이유는 리액트 부작용이다.
    • 원래 Functions는 CJS만 지원했는데 수요가 많아 21년도부터 ESM도 지원하기 시작했다. [참고]
  • prisma 때문에 커스텀 빌드 커맨드를 넣어야 했다. 이걸 참고했다.

📌 호출 테러? 디도스?

Functions를 보며 들었던 의문이다. 누군가 악의적으로 이 함수를 엄청 많이 호출한다면?
물론 공격자에게 금전적 이득이 없으니 세상에 어떤 관종이 그러겠나 싶겠지만, 세상은 넓고 관종은 많다.

인터뷰 Q8

인터뷰에 따르면 rate limit 밖에 별다른 뾰족한 수가 없는 듯 싶다.

해당 사건은 Azure에서 처리해줬다 들었고, AWS의 선례 덕분인지 전반적으로 클라우드 업계에서 비정상 트래픽은 봐주는 관행이 보인다. 하지만 애초에 문제가 안터지는 것이 좋지 않을까?

rate limit을 걸어도 호출 자체가 곧 과금이니, 과연 서버리스가 웹 백엔드로써의 좋은 '상품'인지는 좀 의구심이 든다. (기술 자체는 흥미롭고 좋다.)

📅 23-01-06

📌 파일 업로드 기능 구현


'Cloud Storage 사용' GCP 문서그 문서를 93.5% 따라한 글


  • BE에서 FE로부터 날라온 이미지 파일 받기
    • multer로 multipart 받아서 처리
  • Postman에서 multipart를 쏘는 법은 다음과 같다.
    • 그런데 json을 text가 아닌 형태로 보낼 수 있을지 알아보아야 한다.
    • 저 쩜쩜쩜을 누르면 Content Type이 있던데 이걸 application/json으로 설정하면..? (내심 기대중)

postman capture

  • BE 인증 미들웨어에서 Authorization 헤더를 못잡길래 로그 찍었더니 authorization으로 되어있다.
    • 범인은 express였다.
    • RFC에 의거하면 HTTP 헤더 필드는 case insensitive라 여기까진 ok..이다.
    • 그런데 express에서 제공하는 메소드의 네이밍에 낚였다. 하단 참고.

📌 header와 headers의 차이

이 답변에 따르면, 다음과 같다고 한다.

  • req.header(=req.get): case-insensitive한 서치
  • req.headers: case-sensitive, JS 객체의 프로퍼티 서치

다시말해

req.header('aUtHoRiZaTiOn') // ok
req.header('Authorization') // ok
req.header('authorization') // ok

req.headers['authorization'] // ok
req.headers['Authorization'] // ERROR

이렇다는 것이다.

그런데 headers의 s가 더 광범위한 서치를 의미하는 줄 알고 바꿔쓴 것이 원인이었다. express가 모든걸 lowercase로 눌러버리는데 대문자 들은 것을 찾으라 했으니😑

📅 23-01-13

📌 이메일 인증 기능 구현

인증 이메일 캡쳐

  • nodemailer를 이용한 이메일 발송
    • NODEMAILER_USERNODEMAILER_PASS라는 2가지 환경변수가 들어간다.
  • 인증코드 방식: 보안을 위해 정수코드는 피하기로 하였다. 지금도 좀 허술한 것 같지만..
  • ejs로 메일 내용 렌더링
  • 프로젝트 이메일은 gmail을 선택
    • 환경변수에 로그인하듯 계정 아이디/비번을 넣으니 Bad Credential이라고 한다.
    • 찾아보니 less secure sign-in을 쓰면 된다는데, 더 알아보니 이 방법은 outdated였다.
    • 22년 5월부터 구글 정책이 바뀌어서 2-step verification 설정 후 app password를 발급해야 한다. [참고]
    • app password도 보안 상 좋지는 않다고 한다. 근데 env 푸시하는 바보짓만 안하면 될듯?
  • regex로 특정 학교 이메일인지 검사
    • RegExp로 test하면 boolean result를 반환한다.
// 학교 이메일이 asdf.edu일 경우
const emailRegExp = new RegExp("^[a-zA-Z0-9._%+-][email protected]$");
console.log(emailRegExp.test('[email protected]'));
  • 인증코드 일치 검사
    • 인증 이메일 발송 성공하면 Redis에 '이메일-코드' 형식으로 저장 (exp: 5분)
    • /auth/user/email/code에서 POST로 받아서 Redis 데이터와 일치하는지 검사
      • 잘못된 이메일을 받을때 500으로 주고 있어서 해당 부분 보수가 필요하다.