JWT토큰

2025. 3. 13. 21:04백엔드/NODE.JS

728x90

 

1. JWT란 무엇인가?

  • 정의:
    JWT는 JSON 객체를 사용해 정보를 안전하게 전송하기 위한 토큰입니다. 서버는 이 토큰에 서명을 하여 데이터의 무결성을 보장하며, 클라이언트는 이를 이용해 인증된 요청을 할 수 있습니다.
  • 주요 특징:
    • 자체 포함(self-contained): 토큰 자체에 사용자 인증과 관련된 모든 정보를 담고 있어 별도의 세션 저장소가 필요하지 않습니다.
    • 서명(Signature): 토큰은 비밀 키를 사용해 서명되므로, 토큰이 위변조되지 않았음을 보장합니다.
    • 유효기간(expiration): 토큰에는 만료 시간이 포함될 수 있어, 일정 시간이 지나면 더 이상 유효하지 않도록 할 수 있습니다.

공식 문서 및 참고 자료: JWT 공식 웹사이트


2. JWT 토큰의 구성

JWT 토큰은 세 부분으로 구성되며, 각각 Base64Url로 인코딩되어 .(점)으로 구분됩니다.

  1. Header (헤더):
    • 토큰의 타입(JWT)과 해싱 알고리즘(예: HMAC SHA256)을 포함합니다.
    • 예시: 
    • { "alg": "HS256", "typ": "JWT" }
  2. Payload (페이로드):
    • 실제 전달할 정보(클레임; claims)를 포함합니다.
    • 클레임에는 등록된 클레임(iss, exp, sub 등), 공개 클레임, 그리고 사용자 정의 클레임(예: 사용자 ID)이 있습니다.
    • 예시:
      {
        "id": "userId123",
        "exp": 1630425600
      }
      
  3. Signature (서명):
    • 헤더와 페이로드를 결합한 후, 비밀 키를 사용해 생성한 서명입니다.
    • 이 서명을 통해 토큰의 무결성을 검증할 수 있습니다.
    • 생성 방식:
      HMACSHA256(
        base64UrlEncode(header) + "." + base64UrlEncode(payload),
        secret
      )
      

3. 토큰 생성 (generateToken 함수)

const generateToken = (id) => {
  return jwt.sign({ id }, process.env.JWT_SECRET, { expiresIn: "1h" });
};
  • jwt.sign:
    • 주어진 페이로드(여기서는 { id })를 기반으로 JWT 토큰을 생성합니다.
    • 비밀 키: process.env.JWT_SECRET를 사용하여 토큰에 서명합니다. 이 키는 외부에 노출되면 안 되며, 환경변수로 관리하는 것이 좋습니다.
    • 옵션 (expiresIn):
      • { expiresIn: "1h" } 옵션은 토큰의 유효기간을 1시간으로 설정합니다.
      • 이 옵션은 토큰의 exp 클레임에 반영되어, 지정된 시간이 지나면 토큰이 만료됩니다.

공식 문서(예: node-jsonwebtoken GitHub)에서는 이와 같은 사용법을 자세히 설명하고 있습니다.


4. 토큰 검증 (verifyToken 미들웨어)

const verifyToken = (req, res, next) => {
    const authHeader = req.headers.authorization;
    if (!authHeader || !authHeader.startsWith("Bearer ")) {
      return res.status(401).json({ message: "인증 토큰이 없습니다." });
    }
  
    const token = authHeader.split(" ")[1];
  
    try {
      const decoded = jwt.verify(token, process.env.JWT_SECRET);
      req.user = decoded;
      next();
    } catch (error) {
      return res.status(401).json({ message: "유효하지 않은 토큰입니다." });
    }
};
  • 토큰 추출:
    • HTTP 요청의 Authorization 헤더에서 "Bearer TOKEN" 형식으로 전달된 토큰을 추출합니다.
  • jwt.verify:
    • 추출된 토큰과 비밀 키를 사용하여 토큰을 검증합니다.
    • 토큰이 유효하다면, 페이로드가 decoded 객체에 담기며, 이를 req.user에 할당하여 이후 미들웨어나 라우터에서 사용할 수 있도록 합니다.
    • 유효하지 않거나 만료된 토큰일 경우, 예외가 발생하여 401 상태 코드와 함께 에러 메시지를 반환합니다.
  • 미들웨어 흐름:
    • 토큰이 정상적으로 검증되면 next()를 호출하여 다음 미들웨어로 이동합니다.
    • 검증 실패 시, 요청이 중단되고 클라이언트에 에러 응답을 전달합니다.

5. 주의사항 및 공식 문서 참고

  • 보안 관리:
    • 비밀 키(JWT_SECRET)는 외부에 노출되지 않도록 안전하게 관리해야 합니다.
    • HTTPS를 사용해 통신하면 토큰 도난 위험을 줄일 수 있습니다.
  • 토큰 저장:
    • 클라이언트에서는 토큰을 안전하게 저장할 필요가 있습니다.
    • 로컬 스토리지에 저장하면 XSS 공격에 취약할 수 있으므로, HTTP-Only 쿠키에 저장하는 방법을 고려할 수 있습니다.
  • 토큰 만료:
    • 토큰의 유효기간을 적절히 설정하여, 만료된 토큰이 사용되지 않도록 관리합니다.
    • 만료된 토큰의 경우, 재인증을 유도하거나 리프레시 토큰 방식을 사용할 수 있습니다.

공식 문서를 참고하면 JWT.io에서 JWT의 구조와 사용법, jsonwebtoken GitHub에서 Node.js에서 JWT를 사용하는 방법에 대해 보다 자세한 내용을 확인할 수 있습니다.


6. 결론

  • JWT 토큰 생성:
    • generateToken 함수는 사용자 ID를 페이로드로 하여 JWT를 생성하며, 비밀 키와 유효기간 옵션을 사용해 안전하게 서명합니다.
  • JWT 토큰 검증:
    • verifyToken 미들웨어는 클라이언트 요청의 Authorization 헤더에서 토큰을 추출하고, jwt.verify로 토큰의 무결성과 유효성을 검증하여 인증된 요청임을 확인합니다.

 

728x90

'백엔드 > NODE.JS' 카테고리의 다른 글

Render란?  (0) 2025.03.13
카카오 로그인  (0) 2025.03.13
몽고디비 추가 자동화  (0) 2025.03.13
MongoDB ,Mongoose  (0) 2025.03.13
등록 API,  (0) 2025.03.13