노드숙련_2

·2022년 12월 19일
0

JWT

  • JSON 형태의 데이터를 안전하게 교환하여 사용할 수 있게 해줌
  • 특정한 JSON형식을 암호화해서 JWT로 만듦
  • 인터넷 표준으로서 자리잡은 규격
  • 여러가지 암호화 알고리즘을 사용할 수 있음 ex) SHA-256
  • header.payload.signature의 형식으로 3가지의 데이터를 포함
  • JWT 형식으로 변환 된 데이터는 항상 2개의 .이 포함

JWT 구조

  • header: signature에서 어떤 암호화를 사용하여 생성된 데이터인지 표현
  • payload: 개발자가 원하는 데이터를 저장
    세션을 사용하기 위한 열쇠에 대한 키, 유저 ID에 대한 정보
    => iat; 실제 저장된 시간대
  • signature: 이 토큰이 변조되지 않은 정상적인 토큰인지 확인할 수 있게 도와줌
    jwt토큰을 암호화할 때 특정한 키를 통해서 암호화를 했는지,
    언제까지 만료되는 토큰인지에 대한 데이터

알아두어야 할 특성

  • JWT는 암호 키를 모르더라도 복호화가 가능
    따라서 누구나 정보를 열람할 수 있음(민감한 정보 담지X)

쿠키, 세션과의 차이점

쿠키는 서버에서 전달 받은 것을 다음 서버에 자동적으로 전송
세션은 서버로부터 열쇠를 발급 받아 서버에 있는 자물쇠를 열음

  • 쿠키, 세션
    데이터를 교환 및 관리
  • JWT
    단순히 데이터를 표현하기 위해 암호화압축하는 형식

JWT로 만든 데이터를 브라우저로 보내도 쿠키처럼 자동으로 저장되지는 않지만, 변조가 거의 불가능하고 서버에 데이터를 저장하지 않기 때문에 서버를 Stateless(무상테)로 관리

  • Stateless= 무상태
    Node.js 서버가 언제든 죽었다 살아나도 똑같은 동작을 함
  • Stateful = 상태보존
    서버가 죽었다 살아났을 때 조금이라도 동작이 다른 경우
    ex) 로그인 정보를 서버에 저장하는 경우

가정) 쿠키안에 JWT를 전달 받았다
서버가 꺼졌다 켜저도 JWT 안의 정보들은 없어지지 않는다
= 서버가 똑같은 동작을 함
= JWT에 대한 내용은 Stateless 함
따라서 동일한 데이터를 서버로 전송할 수 있음

JWT 사용 방법

  • 오픈소스 라이브러리: jsonwebtoken 라이브러리 사용
  1. 모듈 설치
npm init
npm i jsonwebtoken -S
  1. JSON 데이터 암호화
const jwt = require("jsonwebtoken");

const token = jwt.sign({ myPayloadData: 1234 }, "mysecretkey");
console.log(token);
  • 확인: jwt.io
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJteVBheWxvYWREYXRhIjoxMjM0LCJpYXQiOjE2NzE1OTI1OTJ9.mJYi7NPBWt9WPLDy42dNy4lPDChsWwDHjs6Yem8avFg
    와 같이 세 부분으로 나뉨
  1. JSON 데이터 복호화
const jwt = require("jsonwebtoken");

const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJteVBheWxvYWREYXRhIjoxMjM0LCJpYXQiOjE2Njc1NjE0NDB9.nvYSsLsT8jp7IfkbB2seCNeuLqRBgrrzDjKRFXjvoUE";
const decodedValue = jwt.decode(token);
  • 확인: { myPayloadData: 1234, iat: 1671594354 }
  1. 복호화가 아닌, 변조되지 않은 데이터인지 검증
const jwt = require("jsonwebtoken");

const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJteVBheWxvYWREYXRhIjoxMjM0LCJpYXQiOjE2Njc1NjE0NDB9.nvYSsLsT8jp7IfkbB2seCNeuLqRBgrrzDjKRFXjvoUE";
const decodedValueByVerify = jwt.verify(token, "mysecretkey");
  • 확인: { myPayloadData: 1234, iat: 1671594354 }

만약 변조된 코드라면 에러가 발생

JsonWebTokenError: invalid signature
  1. 만료시간 설정
const token = jwt.sign(
	{ myPayloadData: 1234 }, 
	"mysecretkey",
	{expiresIn: new Date().getMinutes() + 1}
);
  • 확인: { myPayloadData: 1234, iat: 1671594612, exp: 1671594663 }

최종

async function main() {
    // 암호화
    const jwt =  require("jsonwebtoken");

    const token = jwt.sign(
        { myPayloadData: 1234 },  // jwt를 이용해서 payload 설정하는 부분 
         "mysecretkey",          // jwt를 이용해서 암호화를 하기 위한 비밀 키
         // {  expiresIn: new Date().getMinutes() + 1    } // 만료 시간 지정
         {   expiresIn: "1s"    } // 만료 시간 지정  // expiresIn은 string, number형을 받을 수 있음
        );       
    // console.log(token);
    setTimeout(() => {
        // 복호화
        const decodeToken = jwt.decode(token); // jwt의 Payload를 확인하기 위해서 사용
        // console.log(decodeToken);

        // 비밀 키 검증
        // 1. 암호화를 할 때 사용한 비밀키가 일치하는지 검증
        // 2. 해당하는 jwt가 만료되었는지 검증
        const verifyToken = jwt.verify(token, "mysecretkey");
        console.log(verifyToken);
    }, 1500);           // 1.5초 뒤 실행
    
}

암호화된 데이터 사용 방법

쿠키에 jwt를 전달받은 다음, 서버 요청 시 req부분에 자동적으로 쿠키가 할당 되도록 함

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

실제 사용 용도

  • 회원가입: 회원권 구매
  • 로그인: 회원권으로 놀이공원 입장
  • 로그인 확인: 놀이기구 탑승 전마다 유효한 회원권인지 확인
  • 내 정보 조회: 내 회원권이 목에 잘 걸려 있는지 확인하고, 내 이름과 사진, 바코드 확인
profile
개발자가 되는 과정

0개의 댓글