dh_0e

[Node.js] 강의 내용 개념 정리(4) (JWT) 본문

내일배움캠프/Node.js[숙련]

[Node.js] 강의 내용 개념 정리(4) (JWT)

dh_0e 2024. 5. 24. 20:50

JWT(Json Web Token)

  • 서버와 클라이언트 사이에서 정보를 안전하게 전송하기 위해 도움을 주는 웹 토큰
  • Json 형태의 데이터를 안전하게 전송하고 검증할 수 있음
  • 인터넷 표준으로서 자리잡은 규격
  • 다양한 암호화 알고리즘을 사용할 수 있어 신뢰성을 보장
  • header, payload, signature의 형식으로 3가지의 데이터를 포함
  • 때문에 JWT 형식으로 변환된 데이터는 항상 2개의 점(.)이 포함된 데이터여야 함

JWT - Header, Payload, Signature

JWT의 구조

크게 세 부분, 헤더(Header), 페이로드(Payload), 서명(Signature)로 구성되어 있으며 각각은 점(.)으로 분리됨
  • Header: 헤더는 토큰의 타입어떤 암호화를 사용하여 생성된 데이터인지 정의되어 있음
{
  "alg": "HS256", // HS256으로 암호화
  "typ": "JWT" // JWT 토큰으로 정의
}
  • Payload: 페이로드는 실제 전달하려는 데이터를 담고 있음
{
  "sub": "1234567890", // 실제 전달하려는 내용
  "name": "John Doe", // 실제 전달하려는 내용
  "iat": 1516239022 // JWT가 언제까지 유용한지에 대한 내용
}
  • Signature: 서명은 헤더와 페이로드, 그리고 비밀 키(Secret Key)를 이용하여 생성되어 토큰이 변조되지 않은 정상적인 토큰인지 확인할 수 있게끔 해줌
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
	secret
)
각 부분을 Base64로 인코딩하여 점(.)으로 연결하면 최종적인 JWT를 생성할 수 있음
생성된 JWT는 쿠키(Cookie) 또는 Path Parameter를 통해 전달될 수 있음

 

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

 

JWT의 특성

1. JWT는 비밀 키를 모르더라도 복호화(Decode)가 가능함

  • JWT를 가진 사람이라면 누구나 해당 토큰에 어떤 데이터가 담겨있는지 확인 가능
  • 변조만 불가능할 뿐, 누구나 복호화하여 보는 것이 가능함

2. 민감한 정보(개인정보, 비밀번호 등)는 담지 않아야 함

  • JWT의 페이로드는 누구나 복호화하여 볼 수 있기 때문

3. JavaScript와 같이 특정 언어에서만 사용 가능한 것이 아님

  • JWT는 단순히 데이터 형식일 뿐, 단지 개념으로서 존재하며 이 개념을 코드로 구현하여 공개된 코드를 우리가 사용하는 것이 일반적임

 

JWT와 쿠키, 세션의 차이

데이터를 교환하고 관리하는 방식인 쿠키/세션과 달리, JWT는 단순히 데이터를 표현하는 형식
  • JWT로 만든 데이터변조가 어렵고, 서버에 별도의 상태 정보를 저장하지 않으므로 서버를 Stateless(무상태)로 관리할 수 있음
  • 쿠키와 세션은 데이터를 서버에 저장하므로 Stateful(상태 유지)하게 데이터가 관리됨
  • Node.js 서버가 언제든 죽었다 살아나도 똑같은 동작을 하면 Stateless(무상태)
  • 서버가 죽었다 살아났을 때 조금이라도 동작이 다른 경우 Stateful(상태 유지)
  • 서버가 스스로 어떤 기억을 갖고 결정을 하는 지의 차이
  • 로그인 정보를 서버에 저장하면 무조건 Stateful(상태 유지)이라 볼 수 있음

 

JWT 사용 방법

  • 프로젝트 초기화 및 라이브러리 설치
yarn init -y

yarn add jsonwebtoken express

 

  • jsonwebtoken 라이브러리의 sign 메서드를 사용하여 JSON 데이터 암호화
import jwt from 'jsonwebtoken';

const token = jwt.sign({ myPayloadData: 1234 }, 'mysecretkey');

 

  • jsonwebtoken 라이브러리의 decode 메서드를 사용하여 JWT 복호화
const decodedValue = jwt.decode(token);

console.log(decodedValue);

 

  • jsonwebtoken 라이브러리의 verify 메서드를 사용하여 JWT 검증
const decodedValueByVerify = jwt.verify(token, "mysecretkey");

console.log(decodedValueByVerify);

 

ex)

import express from "express";
import JWT from "jsonwebtoken";

const app = express();

app.post("/login", (req, res) => {
  // 사용자 정보
  const user = {
    userId: 1314,
    email: "znfnfns0365c@gmail.com",
    name: "김동헌",
  };

  // 사용자 정보를 JWT로 생성
  const userJWT = JWT.sign(
    user, // user 변수의 데이터를 payload에 할당
    "secretOrPrivateKey", // JWT의 비밀키를 secretOrPrivateKey라는 문자열로 할당
    { expiresIn: "1h" } // JWT의 인증 만료시간을 1시간으로 설정
  );

  // userJWT 변수를 sparta 라는 이름을 가진 쿠키에 Bearer 토큰 형식으로 할당
  res.cookie("sparta", `Bearer ${userJWT}`);
  return res.status(200).end();
});

app.listen(5002, () => {
  console.log(5002, "번호로 서버가 켜졌어요!");
});