본문 바로가기
TIL

[TIL] JWT(Json Web Token)

by 쾌횽 2024. 2. 2.
반응형

🧐 JWT

JWT(Json Web Token)은 웹 표준으로써, 서버와 클라이언트 사이에서 정보를 안전하게 전송하가 위해 도움을 주는 웹 토큰이다.

JWT는 크게 세부분으로 Header, Payload, Signature로 구성되어 있다. 각 부분은 점(.)으로 분리된다.

  • Header :  헤더는 토큰의 타입과 어떤 암호화를 사용하여 생성된 데이터인지 정의되어 있다.
  • Payload : 페이로드는 실제 전달하려는 데이터를 담고 있다. 개발자가 원하는 데이터를 저장한다.
  • Signature : 서명은 헤더와 페이로드, 그리고 비밀 키(Secret Key)를 이용해서 생성된다. 토큰이 변조되지 않은 정상적인 토큰인지 확인 할 수 있게 도와준다.

🧐 JWT는 쿠키, 세션과 어떻게 다를까?

데이터를 교환하고 관리하는 방식인 쿠키, 세션과 달리, JWT는 단순히 데이터를 표현하는 방식이다.

  • JWT는 변조가 어렵고 서버에 별도 상태 정보를 저장하지 않기 때문에, 서버를 Stateless(무상태)로 관리할 수 있다.
  • 쿠키와 세션은 사용자의 로그인 정보나 세션 데이터를 서버에 저장하므로 상태를 유지한다. 때문에, Stateful(상태보존)하게 데이터가 관리된다.
  • Stateless(무상태)와 Stateful(상태 보존)의 차이는,
    Node.js서버가 언제든 죽었다 살아나도 똑같은 동작을 하면 Stateless하다고 볼 수 있다.
    반대로 서버가 죽었다 살아났을때 조금이라도 동작이 다른 경우 Stateful하다고 볼 수 있다.

🧐 JWT 사용해보기

//yarn을 이용해 프로젝트를 초기화
yarn init -y

//JWT, express라이브러리 설치
yarn add jsonwebtoken express

 

//jwt-test.js
import jwt from "jsonwebtoken";

const token = jwt.sign({ myPayloadData: 1234 }, "mysecretkey");
console.log(token); 
//eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJteVBheWxvYWREYXRhIjoxMjM0LCJpYXQiOjE3MDY4NTk0NDF9.uVKeYV_JQhXwsYX5ZPKrisdJy8z8vkBc56CX8vHQ5Ew

sign이라는 메서드를 통해서 {}안에 payload인 정보를 넣어주고, "mysecrestkey"라는 비밀키를 설정해준다.

 

복호화

decode()로 암호를 복호화할 수 있다.

import jwt from "jsonwebtoken";

const token = jwt.sign({ myPayloadData: 9999 }, "mysecretkey");
console.log(token);
//eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJteVBheWxvYWREYXRhIjo5OTk5LCJpYXQiOjE3MDY4NTk3MDh9.QQy2ejgQphYZMorn0nNWlxB4etxckn2Y7MTH5rJjOQ4

//복호화
const decodedValue = jwt.decode(token);
console.log(decodedValue);
//{ myPayloadData: 9999, iat: 1706859708 }

 

변조 검증

verify()를 통해 토큰이 변조됐는지 확인한다.

만약 "mysecrestkey"가 다른 문자로 작성되어있다면 에러가 발생하게 된다.

//jwt 변조 검증
const decodedValueByVerify = jwt.verify(token, "mysecretkey");
console.log(decodedValueByVerify);
//{ myPayloadData: 9999, iat: 1706859903 }

 

🧐 JWT를 왜 써야하나?

1. JWT가 인증 서버에서 발급되었는지 위변조 여부를 확인할 수 있다.

2. 누구든지 JWT 내부에 들어있는 정보를 확인할 수 있다.(복호화)

 

jwt를 적용하지 않은 로그인 API

import express from "express";
const app = express();

app.post("/login", function (req, res, next) {
  const user = {
    //사용자 정보
    userId: 203, //사용자의 고유 아이디 (Primary key)
    email: "sparta123@gmail.com", //사용자의 이메일
    name: "르탄이", //사용자의 이름
  };

  res.cookie("sparta", user); //sparta 라는 이름을 가진 쿠키에 user 객체를 할당합니다.
  return res.status(200).end(); //**
});

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

** 서버에서는 아무런 데이터를 response로 전달하지않고 쿠키만 전달하게 된다.

쿠키쪽을 확인해 보면,

 

jwt를 적용한 로그인 API

import express from "express";
import jwt from "jsonwebtoken"; //jwt를 가져온다.

const app = express();

app.post("/login", async function (req, res, next) {
  const user = {
    //사용자 정보
    userId: 203, //사용자의 고유 아이디 (Primary key)
    email: "sparta123@gmail.com", //사용자의 이메일
    name: "르탄이", //사용자의 이름
  };

  const userJWT = jwt.sign(user, "mysecrestkey", { expiresIn: "1h" }); //expiresIn을 통해 1시간의 만료시간을 설정

  res.cookie("jwt-express", userJWT);
  return res.status(200).end();
});

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

 

이렇게 암호화된 데이터는 클라이언트(브라우저)가 전달받아 다양한 (쿠키, 로컬스토리지 등)을 저장하여 API서버에 요청을 할 때 서버가 요구하는 HTTP인증 양식에 맞게 보내주어 인증을 시도한다.

 

반응형

'TIL' 카테고리의 다른 글

[TIL] express-session  (0) 2024.02.06
[TIL] Access Token & Refresh Token  (0) 2024.02.02
[TIL] 개인과제 초기 설계  (0) 2024.01.31
[TIL] 쿠키와(Cookie) 세션(Session)  (0) 2024.01.30
[TIL] 트랜잭션(Transaction)  (1) 2024.01.29

댓글