JWT

김동현·2023년 6월 20일
1

JWT란?

  • JSON 형태의 데이터를 안전하게 교환하여 사용할 수 있게 해준다.

  • JSON 웹 토큰은 선택적 서명 및 선택적 암호화를 사용, 데이터를 만들기 위한 인터넷 표준

  • 여러가지 암호화 알고리즘을 사용할 수 있다.

  • header.payload.signature의 형식으로 3가지의 데이터를 포함

  • JWT형식으로 변환 된 데이터는 항상 2개의 .이 포함된 데이터여야 한다.
    이미지 출처 : https://ko.wikipedia.org/wiki/JSON_%EC%9B%B9_%ED%86%A0%ED%81%B0
    이미지 출처 : 스파르타 코딩클럽 제공 학습자료

  • : signature에서 어떤 암호화를 사용할지 확인 후 어떤 암호화를 이용해 생성된 데이터인지 표현을 한다.

<script>
	"alg" : "HS256", // alg key => 어떤 알고리즘을 통해서 JWT가 만들어졌는지 확인
    				 // 해당 JWT 예시는 SHA256암호화 알고리즘을 이용해 만들어짐
    "typ" : "JWT"    // typ => JWT의 타입을 나타낸다.
</script>
  • PAYLOAD

    : 개발자가 원하는 데이터를 저장한다.
    => 해당하는 사용자에게 JWT를 전달, 클라이언트가 전달 받은 JWT를 다시 서버로 보낸다.
<script>
	"sub" : "1234567890",
    "name" : "John Doe",
    "iat" : 1516239022
</script>
  • VERIFY SIGNATURE

    : SIGNATURE는 현재 이 토큰이 변조되지 않은 정상적인 토큰인지 확인할 수 있게 도와준다.
    => 내가 만든 JWT가 동일한지 확인할 때 secret Key가 필요하다.
<script>
	HMACSHA256(
    	base64UrlEncode(header) + "." +
        base64UrlEncode(payload),
        your-256-bit-secret  // 비밀키 삽입 => 만든 JWT가 내가 만든 비밀키로 만들어졌는지 확인
        					 // 인증을 하게 되는 부분
    ) secret base64 encoded
</script>

JWT 특성

  • JWT는 비밀 키를 모르더라도 복호화(Decode)가 가능하다.
  • 누구나 복호화하여 데이터를 볼수있다.
    ㄴ 단, 변조는 불가능하다.
  • 민감한 정보는 담지 않도록 주의해야한다.

cookies, session과 다른점?

  • 데이터를 교환하고 관리하는 방식인 쿠키, 세션과 달리 JWT는 단순히 데이터를 표현하는 방식이다.
  • JWT로 만든 데이터를 브라우저로 보내도 쿠키처럼 자동 저장되지는 않지만, 변조가 거의 불가능하고 서버에 데이터를 저장하지 않아 서버를 Stateless(무상태)로 관리할 수 있다.

JWT 사용법

오픈 소스 라이브러리 이용

  • josnwebtoken 라이브러리 사용
<bash>
	npm init -y
    npm install jsonwebtoken
</bash>
  • 데이터 암호화
<script>

const jwt = require("jsonwebtoken");

const payloadData = {
    myPayloadData : 1234
}

const token = jwt.sign(payloadData, "mysecretKey") // jwt 생성, (넣을 데이터, "비밀 키")
console.log(token);

const decodedValue = jwt.decode(token) // 복호화
console.log("복호화한 token 입니다.", decodedValue);

// jwt 생성했을 때, 사용한 비밀키가 일치하는지 검증
const decodedValueByVerify = jwt.verify(token,"mysecretKey");
console.log("decodedValueByVerify : ", decodedValueByVerify);

// jwt 생성했을 때, 사용한 비밀키가 일치하는지 검증 => 에러 발생
const decodedValueByVerifyToError = jwt.verify(token,"wrongKey");
console.log("decodedValueByVerify : ", decodedValueByVerifyToError);
//JsonWebTokenError: invalid signature 에러 발생

</script>

.을 기준으로 header.payload.signature => jwt.io 사이트에서 확인 가능하다.


본문에서 작성한 "myPayloadData"를 확인할 수 있다.

JWT 사용 이유

  • 누구든지 내부에 들어있는 정보 확인 및 위변조 여부 확인이 가능하다.
<script>

ex) JWT 적용하지 않은 로그인 API

const express = require('express');
const app = express();

app.post('/login', function (req, res, next) {
  const user = { // 사용자 정보
    userId: 422, // 사용자의 고유 아이디 (Primary key)
    email: "eternalife9999@gmail.com", // 사용자의 이메일
    name: "김동현", // 사용자의 이름
  }

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

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

</script>

ex) JWT 적용하지 않은 로그인 API 결과
ㄴ 유저 ID와 Email, Name 모두 노출된다.
ㄴ 브라우저에서 변경이 가능하기 때문에 변경 후 서버로 전송시 문제가 발생할 수 있다.

<script>
ex) JWT 적용한 로그인 API 

const express = require("express");
const JWT = require("jsonwebtoken");
const app = express();

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

  // 사용자 정보를 JWT로 생성
  const userJWT = await 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, "번호로 서버가 켜졌어요!");
});


</script>

ex) JWT 적용한 로그인 API 결과
JWT가 생성된것을 확일할 수 있다.

profile
다양한 기술을 이해하고 응용하는 개발자를 꿈꾸는 예비 개발자

0개의 댓글