백엔드 실습(12)

wltjd1688·2025년 3월 24일

풀사이클

목록 보기
39/74

이번에는 기존에 만든 jwt토큰을 이용해서 인증절차를 만들 수 있도록 할 예정이다.
jwt 사용해서 user조회하기 req.header."Authorization"을 사용할것이다.
먼저 헤더에 토큰 담는걸 연습한 후에 시도해보자

좋아요 추가 API에 jwt 구현

기존에 body에서 user_id를 받던걸 jwt쿠키에 id를 추가해서 가져올 수 있도록 구현함

let recivedJWT = req.headers["authorization"];
let decodedJWT = jwt.verify(recivedJWT, process.env.SECRTE_KEY)

좋아요 취소 API에 jwt 구현, user_id 꺼내기 모듈화

위에껄 함수로 만든다.

function ensureAuthorization(req) {
    let recivedJWT = req.headers["authorization"];
    let decodedJWT = jwt.verify(recivedJWT, process.env.SECRTE_KEY)

    return decodedJWT
}
// 클린코드에서는 이렇게 여러곳에 사용되는건 전체 코드를 한번만 읽을 수 있도록 아래에 나두란다.
// 이름 같은건 동사를 이용하고, 직관적인 이름을 사용하는게 좋다.

jwt expired

TokenExpiredError: jwt expired

JWT 토큰 유효기간이 지나서 500 에러가 났다. 이걸 핸들링 할 수 있어야한다.
원래는 예상 가능한 에러에 대해서 if...else를 사용하는데, 예외(개발자가 생각하지 못한 에러)에 대한 처리를 할 때는 try...catch문을 사용할 수 있다.
이걸 이용해서 유효기간이 지난 토큰이라면 '로그인(인증) 세션(유지되는 상태가)이 만료되었습니다. 다시 로그인 하세요.'라는 메세지를 띄울 수 있도록 만들어 줄것이다.

JWT 예외처리

  • TokenExpiredError: 유효기간이 지난 토큰 = 만료된 토큰
  • JsonWebTokenError: 문제 있는 토큰

try catch 구문 동작 원리 제대로 파헤치기

드디어!! try...catch를 사용한다.

개발자가 예상하지 못한 에러(실수, 사용자 입력을 잘못한 것, 디비가 응답을 잘못한 경우...등등)를 처리하는 문법

예상하지 못한 에러보다는 프로그램에서 일어나는 수 많은 에러들
if...else로 커버하지 못하는 것들에 대한 걸 다룰때 사용한다.

let string = '{"num1":1'

try{
    username; // ReferenceError
    let json = JSON.parse(string); //SyntaxError
    console.log(json)
}catch(err){
    console.log(err);
}
  • try 구문의 코드를 실행하다가 에러가 발생하면, try 코드를 "멈추고" => catch로 err와 함꼐 바로 빠져나간다.
  • try 구문에서 어떤 에러가 발생해도, 우리가 다 if문 분기 처리를 해주던 내용들이 => 알아서 catch에 잡혀요.

에러 객체

자스가 고대 개발자들의 노고를 보고,"내장" 에러 객체를 만들어 뒀다.
JWT라는 모듈에서 제공하는 에러 객체도 있고,
여러분들이 직접 만들어쓸 수 있는 에러객체도 있다.

// ReferenceError: username is not defined
// ... 
 console.log(err.name);		// ReferenceError
 console.log(err.message);	// username is not defined

Throw 연산자

에러를 발생시키는 연산자...?

// throw 에러 객체
// ex.throw SyntaxError();
let string = '{"num1":1}'

try{
    let json = JSON.parse(string); 
    
    if(!json.name){
        throw new SyntaxError("입력 값에 이름이 없습니다.")
    } else {
        console.log(json.name);
    }

    let name = json.name;
    console.log(name);
}catch(err){
    console.log(err.name);
    console.log(err.message);
    console.log(err)
}

res를 두번 보내면 생기는 일 - instanceOf 등장

node:_http_outgoing:699
    throw new ERR_HTTP_HEADERS_SENT('set');
    ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

이건 res를 2번 보내기에 생기는 일,
해당 함수를 불러오는 로직에서 res를 변수에 넣었기 때문에, 2번 보내게 되는 것이다.
이때 err를 반환하게 변경하고 다음과 같이 로직에 코드를 추가하여 수정해줄 수 있다.

const getCartItem = (req,res)=>{
    const {selected} = req.body;

    let authorization = ensureAuthorization(req, res)
    if ( authorization instanceof jwt.TokenExpiredError){
        return res.status(StatusCodes.UNAUTHORIZED).json({
            "message": "로그인 세션이 만료되었습니다. 다시 로그인해주세요"
        })
    }
  //...
  
//...
function ensureAuthorization(req,res) {
    try{
        let recivedJWT = req.headers["authorization"];
        console.log(recivedJWT)
        let decodedJWT = jwt.verify(recivedJWT, process.env.SECRTE_KEY)
        return decodedJWT
    } catch(err){
        console.log(err.name);
        console.log(err.message);
        return err
        // return res.status(StatusCodes.UNAUTHORIZED).json({
        //     "message": "로그인 세션이 만료되었습니다. 다시 로그인해주세요"
        // })
    }
}

근데 이게 또 다른 에러는 찾아주지 않는다.
그렇기에 if문을 추가하여 다른 에러에 대해서도 예외처리를 해주어야한다.

ensureAuthorization모듈화 하기

다른 파일에서도 사용하게 되기에, 이걸 모듈화 해주었다.

const jwt = require("jsonwebtoken")
const dotenv = require('dotenv')
dotenv.config();

const ensureAuthorization = (req,res) => {
    try{
        let recivedJWT = req.headers["authorization"];
        let decodedJWT = jwt.verify(recivedJWT, process.env.SECRTE_KEY)
        return decodedJWT
    } catch(err){
        console.log(err.name);
        console.log(err.message);
        return err
    }
}


module.exports = ensureAuthorization
profile
일단 해!!!!

0개의 댓글