학습 - JWT의 학습

YoonSuk Choi·2025년 1월 2일

7주차

목록 보기
6/10

1. JWT란?

  • JWT(JSON Web Token)는 클라이언트와 서버 간의 안전한 정보 교환을 위한 토큰 기반 인증 메커니즘
  • JWT는 사용자 인증 및 정보 전송 시 신뢰성을 보장해준다.

JWT 작동방식

2. JWT 구성

  • Header: 토큰의 타입과 해시 알고리즘 정보가 포함
  • Payload: 실제 정보 데이터가 포함되며, 클레임(claim)이라 불리는 키-값 쌍으로 이루어져 있음
  • Signature: 토큰의 무결성을 검증하기 위한 서명 부분으로, Header와 Payload의 조합에 비밀 키를 사용해 생성

3. 코드 설명

3.1 서버 코드(app.js)

const express = require("express");
const jwt = require("jsonwebtoken");
const app = express();
const PORT = 8080;
const SECRET = "rMaRSWeDfz2NDB7H"; // 보안 강화를 위해 .env 파일에 저장 권장

app.set("view engine", "ejs");
app.use(express.urlencoded({ extended: false }));
app.use(express.json());

const userInfo = {
  id: "cocoa",
  pw: "1234",
  name: "코코아",
  age: 18,
};

app.get("/", (req, res) => res.render("index"));
app.get("/login", (req, res) => res.render("login"));

app.post("/login", (req, res) => {
  const { id, pw } = req.body;
  if (id === userInfo.id && pw === userInfo.pw) {
    const token = jwt.sign({ id }, SECRET);
    res.send({ result: true, token });
  } else {
    res.send({ result: false, message: "로그인 정보가 올바르지 않습니다." });
  }
});

app.post("/token", (req, res) => {
  const token = req.headers.authorization?.split(" ")[1];
  if (token) {
    try {
      const auth = jwt.verify(token, SECRET);
      if (auth.id === userInfo.id) {
        res.send({ result: true, name: userInfo.name });
      }
    } catch {
      res.status(401).send({ result: false, message: "인증된 회원이 아닙니다." });
    }
  } else {
    res.redirect("/login");
  }
});

app.listen(PORT, () => console.log(`http://localhost:${PORT}`));

3.2 로그인 페이지(login.ejs)

<!DOCTYPE html>
<html lang="ko">
<head>
  <title>login</title>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
  <h1>로그인</h1>
  <form name="login-form">
    <input type="text" id="id" placeholder="ID를 입력하세요" />
    <input type="password" id="pw" placeholder="비밀번호를 입력하세요" />
    <button type="button" onclick="login()">로그인</button>
  </form>
  <script>
    async function login() {
      const form = document.forms["login-form"];
      const response = await axios.post("/login", {
        id: form.id.value,
        pw: form.pw.value,
      });
      const { result, token, message } = response.data;
      if (result) {
        localStorage.setItem("login", token);
        document.location.href = "/";
      } else {
        alert(message);
        form.reset();
      }
    }
  </script>
</body>
</html>

3.3 메인 페이지(index.ejs)

<!DOCTYPE html>
<html lang="ko">
<head>
  <title>JWT</title>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
  <h1>JWT</h1>
  <div id="info"></div>
  <script>
    (async function () {
      const token = localStorage.getItem("login");
      const info = document.getElementById("info");
      let data;
      if (!token) {
        data = '<a href="/login">로그인</a>';
      } else {
        const response = await axios.post("/token", {}, {
          headers: { Authorization: `Bearer ${token}` },
        });
        if (response.data.result) {
          data = `<p>${response.data.name}님 환영합니다!</p>
                  <button>로그아웃</button>`;
        }
      }
      info.innerHTML = data;
    })();

    function logout() {
      localStorage.clear();
      document.location.reload();
    }
  </script>
</body>
</html>

4. 실행 및 동작 원리

  1. 사용자는 로그인 페이지에서 ID와 비밀번호를 입력
  2. 서버는 사용자 정보를 검증한 후, JWT를 생성하여 클라이언트에 전달
  3. 클라이언트는 JWT를 로컬 스토리지에 저장
  4. 이후 요청 시, JWT를 헤더에 추가하여 서버로 전송
  5. 서버는 JWT의 유효성을 검증하고 사용자 정보를 반환
  6. 클라이언트는 인증 성공 여부에 따라 페이지를 렌더링하거나 로그아웃을 처리

5. 결론

  • JWT는 보안성과 효율성 면에서 강력한 인증 방식
  • 다양한 웹 애플리케이션에서 사용한다.
profile
Name : 최윤석(YoonSuk Choi)

0개의 댓글