[NodeJS] JWT 사용 이유와 VScode로 JWT 기초를 활용한 토큰 생성 및 검증 해보기

꾸적꾸적·2022년 6월 7일
0

먼저 참고한 사이트 들

JWT 기초 파트 : _woogie JWT 로그인 방식 구현하기 (feat. session에서 jwt로)
구현 파트 : [Node.js] JWT Token 생성 및 검증


엄청 친절하게 기초를 잘 설명해둔 사이트 들이라 참고 많이 했습니다.

사실 이 글에서는 저 기초를 어떻게 써서 했는가로 진행됩니다.

Nodejs는 이번에 처음 다뤄보는 파트라,

이것저것 모르는 부분이 많아서 윗 링크처럼 이곳저곳 찾아다니면서

하나씩 완전히 독학으로 공부하고 있는데.. 엄청 자세하게 알려주는 사이트가 영 없어서

공부하기가 많이 빡셌습니다.


JWT란 무엇인가?

먼저 JWT 방식을 사용하는것이니,

JWT가 무엇인가부터 알아야 하는데,

JWT는 JSON Web Token 의 줄임말로써,
Claim 이라는 속성 정보를 JSON 데이터 구조로 표현한
'토큰' 을 사용하는 방식이라고 합니다.

예를 들자면, 우리가 구글 크롬을 사용해서 로그인 할때

우측 상단에 '비밀번호를 저장하시겠습니까?' 라고 하는게
'Claim 정보를 저장 하시겠습니까? ' 와 같은 의미 같고,

그 값을 저장하면
'Claim 정보를 JSON 데이터 구조로 표현한 토큰으로 쿠키에 저장 하는 방식'

으로 생각합시다.

(매번 혼자서 독학 하기에 나름대로의 쉬운 방법으로 기억하는 습관이 있는데,
이게 맞는지는 확실하진 않음..)

그러면 그 JWT 값은 어떻게 저장이 되는가?

헤더는 JWT의 유형,
페이로드는 JWT에 입력된 해시 알고리즘( SHA256, RSA 등 ),
시그니처는 비밀 키를 암호화 한 부분

이 부분은 뒤에서 더 자세하게 적도록 하겠습니다.

어찌됬건, JWT는 이런식으로 여러 파트로 나누어서 저장된다. 라고 이해합시다.


JWT를 사용하는 이유?

이제 JWT가 무엇인지 알았으니,
왜 JWT를 사용해야 하는가를 알아야겠지요?

일단 기본적으로 JWT는 로그인 정보를 저장하기 위해 사용됩니다.

하지만 이 외에도 Session에 저장하는 방식도 존재하는데,

이 방식은 결국 Session을 계속 유지 해야한다는 단점이 존재합니다.
다시 말하면, 조금은 다르지만 유지가 안되면 날라가는 PC방 부트 디스크를 생각하면 될 듯 합니다.

또한 사용자가 많아지면 Session을 늘려야 커버가 될텐데,
Session을 유지하며 늘린다는 건 가볍게 생각해도 힘듭니다.

따라서, Session을 유지하지 않아도,
브라우저에 저장된 값을 통해 사용이 가능한, JWT 방식이 채택 되었다. 라는 이야기


JWT의 구동 원리?

그러면, JWT는 어떤식으로 구동 되는가?

  1. 브라우저에서 로그인 요청
  2. 서버에서 JWT 발급
  3. 발급한 JWT를 브라우저로 전송
  4. 브라우저에서 이후 로그인 요청시 JWT를 함께 전송
  5. 서버에서 JWT에 포함된 Signature(비밀 키를 암호화 한 부분)를 확인 후, user정보를 request에 추가
  6. 서버에서 브라우저의 로그인 요청을 처리
  7. 서버에서 브라우저로 response를 보내기.

이런식으로 진행된다고 하는데,

이것도 짧게 정리하면,

첫 로그인 시에, 브라우저(사용자)로 서버가 JWT를 발급해서, 이를 브라우저에 저장하고,
이후 로그인 시에, 브라우저(사용자)가 서버로 JWT를 요청과 함께 보내서 확인 후, OK나 NO 사인을 보낸다.

로 정리할 수 있습니다.


JWT 토큰 값 저장 방식?

그러면 이제, JWT값을 통신할 때 어떤 식으로 저장을 하느냐 인데,
이는 또 두가지로 나뉩니다.

  1. response로 보내기 => 로컬 스토리지에 저장
  2. cookie로 보내기 => 브라우저 쿠키에 저장

다만, 1번의 경우, XSS 공격에 취약해서, 2번으로 많이들 결정 합니다.
(이 또한 출처 : _woogie JWT 로그인 방식 구현하기 (feat. session에서 jwt로) 에 설명되어 있음)

문제는, 이세상에 완벽한 보안이란 없기 때문에,
(보안 업계를 가기위해 공부할때마다 듣는 가장 중요한 말)

2번도 CSRF 공격이라는 것이 존재하기 때문에 안전하지 않습니다.
(당연히 이것도 윗 링크에 설명되어 있다)

따라서, 조금더 안전하게 변환된 JWT 방식인,
Access 및 Refresh 토큰을 사용한 방식을 활용해서 구성하기로 했습니다.

(이후, 이를 사용하는 파트에서 더 자세히 적을 예정)

다만, 이 글에서 다루는건 기본 JWT 방식이니 이 더 강화된 부분은

다음 글에서...

사실, 바로 Access 및 Refresh 토큰을 사용하는것도 맞다고 생각하지만,

이왕 JWT 방식을 공부하는거면,

기초부터 차근차근 공부해가면서

이 부분은 왜 이렇게 되는가를 먼저 공부하는 것이 중요하다고 생각했습니다.

(뭐, 사람마다 생각은 다르니까 아니라면 다음 글로 바로 가도 상관은 없다.)


NodeJS에서 JWT토큰을 구현해보자!

이정도면 JWT가 어떤건지 설명이 됬으니,

JWT를 활용해서 기본적인 코드를 구성해봅시다.

지금 만드는 서버의 경우엔,

NodeJS를 활용해서 분업을 하고 있다보니,
NodeJS 환경에서 구축을 해보았습니다.

개발 환경은 VS Code를 사용했습니다.

var express = require('express');
var app = express();
var jwt = require("jsonwebtoken");

app.get('/', function (req, res){
    res.send('This Page is Test Page for understanding JWT');

    var token = jwt.sign({              // Private Claim
        test : "test"
    },
    "secretKey",                        // Signature (비밀 키 자리)
    {
        subject : "JHKkmu JWT Token",   // Public Claim
        expiresIn : '60m',
        issuer : "JHKkmu" 
    });

    console.log("토큰 생성\n", token);
    try{
        var check = jwt.verify(token, "secretKey");
        if(check) {
            console.log("검증", check.test);
        }
    } catch(e){
        console.log(e);
    }
});

app.listen(3000, function(){
    console.log('Example app listening on port 3000');
});입력하세요

새로운 것을 공부할때마다 드는 생각이지만,
재밌으면서도 신기한게,
그렇게 길게 말로 설명하고 외워야하는것을
코드로 적으면 기초는 이렇게 간단하다는것이죠.

이 코드는 기본적으로 어떤식으로 구현이 되는가에 관련해서 만들어둔 코드입니다.
참고 : 구현 파트 : [Node.js] JWT Token 생성 및 검증

이것의 결과값은 localhost:3000에서 실행이 되는데,
그건 맨 마지막줄 app.listen에서 3000에서 실행하라 라고 했기 때문이고,
이후 웹서버에서도 실행 되도록 만들수 있습니다.

위 코드를 실행하면 나오는 localhost:3000 페이지의 화면

참고로 실행을 하게 되면,

터미널에서는 Example app listening on port 3000 이라고 나오고,

그 다음줄에 토큰 생성, 토큰 값이 나오게되며,

var check 부분에서 임의로 준 비밀키 secretKey와 동일하면,

인증이 되었기때문에, 검증 이라는 단어와 Private claim에 넣어준 test가 출력됩니다.

매번 바뀌는 시그니처 부분, 그 외에는 동일한 값이 반복됩니다.

당연히 접속을 한 만큼 터미널에는 여러번 토큰 생성값이 나오지만,
시그니처 부분은 해시알고리즘으로 통해 계속 다른값이 나온다.

Private Claim과 Signature 부분은 이후 랜덤값을 주어 변경하면 되는 부분이고,

이 코드에서는 토큰 하나로 제어 하도록 만들어 둔 것인데,

이를 이제 Access 및 Refresh 토큰을 이용한 JWT 방식으로 변경하여 구현하는것은

다음 글에서 하도록 하겠습니다.

profile
개발자를 꿈꾸는 한 명의 초보 개발자

0개의 댓글