토큰(Token)

JINSUNG LEE·2021년 10월 21일
0
post-thumbnail



사용자 정보를 담는 방식에는 3 tier architecture에서 서버에 저장을 하거나 클라이언트 측에서 저장을 하거나 다양한 방식이 존재한다.

이번 시간에는 클라이언트 측에 인증 정보를 담는 토큰(Token)에 대해 알아보자




Token

그런데 왜 굳이 보안 관련 인증 명칭을 토큰이라고 지었을까 궁금할수도 있다.

놀이동산을 입장하기 위해선 고객들은 티켓을 소유하고 있어야만 입장이 가능하듯, 웹 사이트에서는 토큰을 소유한 사용자만이 해당 웹사이트에 있는 서비스를 누릴 수 있다.

결국 토큰은 명칭 그대로 사용자 신분을 서버에게 제시하는 것과 똑같은 셈이다.

Token 보안에 안전한거 맞긴 맞아?

사용자 즉 클라이언트 측에서 Token을 소지하고 있기에 XSS, CSRF 해커 공격에 위험할 수 있기에 중요한 정보는 저장하면 안될 것이다.

XSS란?
웹 애플리케이션에서 일어나는 취약점으로 관리자가 아닌 권한이 없는 사용자가 웹 사이트에 스크립트를 삽입하는 공격 기법

CSRF란?
인터넷 사용자가 자신의 의지와는 무관하게 해커가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트 주소를 통해 인터넷 사용자 정보를 탈취 당하는 기법

그러나 사용자 정보를 암호화된 상태로 클라이언트 측에 보내기 때문에 큰 위험 리스크가 없다.




jwt (JSON Web Token)



JWT는 JAVA, Javascript, C, C++, swift 등등 다양한 프로그래밍 언어를 지원해주는 웹 토큰 기반 인증 서비스이다.

JWT는 .(점) 기준으로 Header, Payload, Signature 3가지로 나누어져 있다.

Header 영역에는 두가지 옵션을 가지고 있다.

typ: 토큰의 타입을 지정하는데 JWT를 의미한다.
alg: 해싱 알고리즘이며 토큰을 검증할 경우 signature 영역에서 사용된다.


const header = {
  "typ": "JWT",
  "alg": "HS256"
};

Node.js 환경에서 위 정보를 base64 기반에 인코딩하면 JWT의 첫번째 영역이 완성된다.

Payload

Payload 영역에는 토큰에 담아야할 정보를 입력해야 하며 옵션을 다양한다.

iss: 토큰 발급자
aud: 토큰 대상자
sub: 토큰 제목
nbf: Not Before 이라는 단어를 의미로 토큰 활성 날짜를 뜻한다.
exp: 토큰의 만료시간
iat: 토큰이 발급된 시간, 이 값을 통해 토큰의 age가 얼마나 남았는지 판단된다.
jti: JWT의 고유 식별자이며, 중복적인 처리를 방지하기 위해 사용되어 주로 일회용 토큰에 사용한다.


const payload = {
  "email": "caifornialove.96@gmail.com",
  "userName": "Lee",
  "iss": "CaliforniaLuv.com",
  "exp": "1800000000000",
};

단 위 정보를 payload 객체에 담아둘 경우 패스워드 혹은 민감한 정보를 절대로 담아두어서는 안된다.

signature

JWT 최종 구간으로 생성한 header의 인코딩값과 payload의 인코딩값을 결합한 후 비밀키(Salt)에 해쉬 알고리즘을 넣어준다.


HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

header와 payload 인코딩 값 사이에는 반드시 .(점)을 넣어 해쉬 알고리즘을 진행해야한다.

jwt 사이트에 작성한 결과를 그대로 입력하면 해싱으로 암호화된 토큰이 출력된다.

node.js 환경에서 해싱 및 인코딩


const header = {
  "typ": "JWT",
  "alg": "HS256"
};

// encoding from base64
const encodedHeader= new Buffer(JSON.stringify(header))
                            .toString('base64')
                            .replace('=', '');

----------------------------------------------------------------
  
const payload = {
  "email": "caifornialove.96@gmail.com",
  "userName": "Lee",
  "iss": "CaliforniaLuv.com",
  "exp": "1800000000000"
};


// encoding from base64
const encodedPayload= new Buffer(JSON.stringify(payload))
                            .toString('base64')
                            .replace('=', '');


----------------------------------------------------------------

// hashing And encoding
const crypto = require('crypto');
const signature = crypto.createHmac('sha256', 'secret')
             .update(encodedHeader + '.' + encodedPayload)
             .digest('base64')
             .replace('=', '');

console.log('signature: ',signature);




토큰 인증 메커니즘






JWT 장단점



장점

  1. 사용자 인증에 필요한 정보는 토큰에 저장되기 때문에 별도의 인증 공간 및 저장소가 필요 없음
  2. 디버깅 및 관리가 편리
  3. 트래픽 부담 감소
  4. REST 서비스 제공
  5. 내장된 만료로 인해 보안 강도 높음

단점

  1. 클라이언트 즉 사용자 측에게 저장된 관계로 DB에서 사용자 정보를 조작할 경우 토큰 직접 사용 불가
  2. 많은 필드로 인해 토큰 용량 상승




profile
https://californialuv.github.io/Tech_Blog 이사 갔어용 🌎 🚀

0개의 댓글