JWT(JSON Web Token) 모듈 사용법

Myeongjun Park·2022년 10월 10일
0
post-thumbnail

📖 JWT란?

JSON Web Token의 약자로, 토큰 기반의 인증 방식이다.
정보를 JSON 객체에 담아 암호화하여 해싱 작업을 거친 뒤 문자열 토큰을 생성하는 기술로, 클라이언트는 이 토큰을 HTTP Header에 넣고 요청을 보내어 인증을 할 수 있다.
자세한 정보

✅ JWT를 사용하는 이유

권한 부여 : JWT를 사용하기 위한 가장 일반적인 사용처이다.
유저가 로그인을 하게 되면 이후의 각 요청에는 JWT가 포함되어, 사용자가 해당 토큰을 허용된 경로와 서비스 및 리소스에 액세스 할 수 있다.
정보 교환 : JSON Web Token은 당사자 간에 정보를 안전하게 전송하는 좋은 방법이다.
공용키, 개인키를 사용하여 서명할 수 있기 때문에 보낸 사람이 자신이 누구인지 확인이 수월하다.
또한 Header와 Payload를 사용하여 서명을 계산하므로 내용이 위변조 되지 않았는지 확인도 가능하다.

✅ 어떻게 동작할까?

1. 클라이언트에서 ID, PW를 서버로 보낸다.
2. 서버에서 ID, PW 정보를 이용하여 JWT를 생성한다.
3. 서버에서 클라이언트로 JWT를 보낸다.
4. 클라이언트에서 서버로 서비스 요청 시에 JWT를 함께 보낸다.
5. 서버에서 처리할 때 JWT를 검증하고 일치하면 해당 동작을 클라이언트에게 응답한다.

✅ JWT 구성요소

Token은 이름 그대로 JSON 형식을 가지고 있고, . 으로 세 부분을 구분한다.

Header(기본 요소).Payload(전달 할 데이터).Signature(서명)

Header : 일반적으로 토큰의 타입, 해시 함수를 명시하게 된다.

{
"alg": "HS256",
"typ" : "JWT"
}

Payload : 토큰에 담을 클레임(Claim) 정보를 포함한다.
Claim은 payload에 담기는 정보의 한 조각을 말하며, Key-Value 이루어 진다.
즉, 상대방에게 전달한 데이터를 포함한다.

  1. registered claim
    iss : 토큰 발급자
    exp : 토큰 만료 시간
    sub : 토큰 제목
    aud : 토큰 대상자
  2. public claim
    공개적인 claim을 명시한다.
  3. private claim
    서버와 클라이언트가 협의한 claim을 명시한다.
{
"name": "John Doe",
"admin": true
}

Signature: header, payload를 연결, 합친 뒤 비밀키로 해싱한다. 일종의 암호화 작업.

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  your-256-bit-secret
)

위의 세가지 정보를 합쳐서 JWT 방식의 토큰이 만들어지며 토큰은 아래와 같은 형태를 띈다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

✅ JWT 모듈 사용하기

보다 편한 JWT 사용을 위해 jsonwebtoken을 설치한다.

npm install jsonwebtoken

📌 토큰 생성

아래 코드는 로그인 로직인데, JWT 생성하는 것이 목적이므로 불 필요한 부분은 제외하고 작성했다.
자세한 로그인 로직은 다음 포스팅에서 작성하겠다.

import jwt from "jsonwebtoken";

const secret = "secret_key"; //비밀 키 선언
	try {
		const accessToken = await new Promise((resolve, reject) => {
            jwt.sign(
              {
                Id: userItem?.id, //payload에 담을 ID
                Name: userItem?.name, //payload에 담을 Name
              },
              secret, // 비밀 키
              {
                expiresIn: "5m", // 유효 시간 5분
          	  });
    //브라우저에 success와 token을 담아 보낸다.
	res.json({ success: true, accessToken });

📌 토큰 검증, 디코딩

  if (req.method === "GET") {
    var token = req.cookies.LoginToken; //cookie의 토큰을 가져온다.
    let decoded = jwt.verify(token!, secret); //jwt 내장 메소드 verify로 검증하고 디코딩한다.
    if (decoded) {
      res.send(decoded); //디코딩 된 JSON을 클라이언트에게 응답
    } else {
      res.send("권한이 없습니다.");
    }
  }

이렇게 하면 간단한 JWT 생성부터 검증, 디코딩까지 완료된다.

📌 참고
JWT 기반으로 사용자 인증 구현하기
JWT란, 사용하는 이유, 동작방식

profile
머릿속에 잘 들어갔는지 확인하는 곳

0개의 댓글