본문 바로가기

개발/프로그래머스 데브코스

프로그래머스 데브코스 41일차 with. TS 웹 풀스택

📚요약

지난 시간에는 비동기를 활용해 주문 API를 완성했습니다. 이번 시간에는 JWT와 Request의 Headers를 활용해서 API에서 JWT를 활용하는 부분을 전반적으로 수정해 보겠습니다. 추가적으로 try-catch를 활용한 예외 처리도 배워보겠습니다.

 

📖JS

📄에러 객체

에러가 발생하면 에러 메시지가 나오며 어떤 에러인지 어느 부분에서 발생한 것인지를 알려줍니다. 이렇게 에러가 발생할 수 있는 이유는 에러 객체가 존재하기 때문입니다.

  • Error() : 런타임 오류 발생 시 던져지는 오류 객체.
  • SyntaxError() : 구문이 이상한 경우 던져지는 오류 객체.
  • ReferenceError() : 잘못된 참조를 알려주는 오류 객체.
  • EvalError(), RangeError() 등등
let error = new Error('에러 객체');

console.log(error.name); // Error
console.log(error.message); // 에러 객체
console.log(error.stack);
/*
Error: 대장 에러 객체
    at Object.<anonymous> (c:\Users\User\Desktop\TY\다른 컴퓨터\ProgrammersSchool\BASIC-NODE\train-js\Error-train.js:1:13)
    at Module._compile (node:internal/modules/cjs/loader:1369:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1427:10)
    at Module.load (node:internal/modules/cjs/loader:1206:32)
    at Module._load (node:internal/modules/cjs/loader:1022:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:135:12)
    at node:internal/main/run_main_module:28:49
*/

자세한 내용은 MDN 사이트를 참고하면 좋을 것 같습니다.

 

Error - JavaScript | MDN

Error 객체는 런타임 오류가 발생했을 때 던져집니다. Error 객체를 사용자 지정 예외의 기반 객체로 사용할 수도 있습니다. 아래 표준 내장 오류 유형을 참고하세요.

developer.mozilla.org

 

📄try-catch

 try-catch는 try에서 코드를 실행시키고, 예외 또는 에러가 발생한 경우 즉시 실행을 중지하고 catch에서 처리하는 방식의 구문입니다.

try {
  anything;
} catch (err) {
  console.log(err);
}

 

if-else는 진행했던 예외 처리와의 큰 차이점은 실행 중인 코드가 중간에 멈추느냐의 차이입니다. if-else의 경우 에러가 발생하더라도 계속 코드를 실행하는 반면 try-catch는 바로 중지하고 예외 처리를 진행하다는 점에서 좀 더 안전합니다.

 

📑throw 키워드

throw 키워드는 사용자가 정한 예외를 발생시킬 수 있는 키워드입니다. 예외가 발생되면 해당 함수의 실행은 중지되고 catch 블록으로 예외가 던져지는데 catch가 없다면 종료됩니다.

try {
  let obj = {
    email:'kim@mail.com'
  }
  if (!obj.name) {
    throw new SyntaxError("객체에 이름이 없습니다.");
  } else {
    console.log(json.name);
  }
} catch (err) {
  console.log(err.name); // SyntaxError
  console.log(err.message); // 객체에 이름이 없습니다.
}

 

🍯tip! 추가적으로 finally를 같이 사용한다면 에러가 발생하건 잘 동작하든 상관없이 실행시킬 수 있습니다.
try {
  // 동작 코드
} catch (err) {
  // 에러 처리 코드
} finally {
  // 항상 동작하는 코드
}

 

📖JWT 실습

📄복습

const jwt = require('jsonwebtoken');

const token = jwt.sign({ name: "nulzi" }, process.env.PRIVATE_KEY);
console.log(token);

const decoded = jwt.verify(authorization, process.env.PRIVATE_KEY);
console.log(decoded); // { name: 'nulzi', iat: 172737848 }

 

📄모듈 기본 내장 에러

  • TokenExpiredError : 토큰의 유효기간이 만료된 경우 발생하는 에러
  • JsonWebTokenError : 토큰이 유효하지(valid) 않을 때 발생하는 에러
  • NotBeforeError : 현재 시간이 nbf 요청 이전이면 발생하는 에러(Thrown if current time is before the nbf claim)

 

📖주문 API

📄구현

좋아요 & 좋아요 취소 구현

로그인할 때 생성된 토큰을 쿠키에 저장하고, 저장된 토큰을 FE에서 요청 시 Request의 Headers의 Authorization에 담아서 준다고 가정합니다. BE에서는 받아온 요청에서 토큰을 꺼내 jwt 모듈의 verify()를 통해 올바른지 확인하고 데이터를 사용합니다.

(req,res) => {
  // ...
  const userId = decodeUserId(req);
  // ...
}

const decodeUserId = (req) => {
  const token = req.headers.authorization;
  const userId = jwt.verify(token, process.env.PRIVATE_KEY).userId;

  return userId;
};

 

📖장바구니 API

📄구현

장바구니 담기 & 장바구니 예상 목록 조회
장바구니 목록 조회 & 장바구니 개별 삭제

좋아요와 같은 방식으로 jwt를 이용해 사용자 정보를 가져와 장바구니를 다룰 수 있도록 만들었습니다. 차이점은 try-catch를 사용해 예외 처리를 추가했다는 점입니다.

 

📄JWT 예외 처리

TokenExpiredError & JsonWebTokenError

(req, res) => {
  // ...
  const userId = decodeUserId(req, res);

  if (userId instanceof jwt.TokenExpiredError) {
    return res.status(StatusCodes.UNAUTHORIZED).json({
      message: "로그인 세션 만료됨.",
    });
  }

  if (userId instanceof jwt.JsonWebTokenError) {
    return res.status(StatusCodes.BAD_REQUEST).json({
      message: "토큰이 이상합니다. 확인해주세요",
    });
  }
  // ...
}

const decodeUserId = (req, res) => {
  try {
    const token = req.headers.authorization;
    const userId = jwt.verify(token, process.env.PRIVATE_KEY).userId;

    return userId;
  } catch (err) {
    console.log(err.name);
    console.log(err.message);

    return err;
  }
};

 

자세한 코드는 Github에서 확인할 수 있습니다.

 

ProgrammersSchool/PROJECT-BOOKSHOP at main · nulzi/ProgrammersSchool

프로그래머스 데브코스에서 학습하는 것들을 모아두는 레포. Contribute to nulzi/ProgrammersSchool development by creating an account on GitHub.

github.com

 

❔▪❓

Q. 함수명은 어떤 게 가장 좋은 이름일까?

 

Q. 예외 처리를 하는 부분은 어떻게 모듈화 하는 것이 좋을까?

 

다음 시간에 계속...

 

출처 & 참고

김송아 강사님의 강의

throw, MDN, 2024.06.03

try..catch, MDN, 2024.06.03

jsonwebtoken, 공식, 2024.06.03