JWT_11.8

송철진·2022년 11월 8일
0

요약

  • JWT(JSON Web Token): 클라이언트(사용자)와 서버 간에 정보를 JSON 개체로 안전하게 전송하기 위한 개방형 표준(RFC 7519)
  • JWT을 이용한 인증 과정: 사용자 측에서 사용자의 정보를 관리하는 토큰 기반 인증 메커니즘
  • JWT의 3가지 구성 요소. 각 구성 요소들은 dot(.)으로 구분
    • Header: Signature을 만드는데 사용한 알고리즘, Token의 타입 정보
    • Payload: 실질적으로 전달해야 하는 정보(각각 Claim)
    • Signature: (Header의 인코딩된 내용+Payload의 인코딩된 내용)을 Secret Key와 알고리즘으로 암호화된 JWT의 서명 부분

1. JWT(JSON Web Token)

클라이언트(사용자)와 서버 간에 정보를 JSON 개체로 안전하게 전송하기 위한 개방형 표준(RFC 7519)

특징

  • SAML (Security Assertion Markup Language Token) 보다 크기가 작아 더 컴팩트하게 사용할 수 있다.
  • JSON 개체에 기본정보, 전달할 정보, 검증 정보를 모두 담고 있다.
  • 전자 서명이 되어있기 때문에 검증 과정을 거쳐 확인하고 신뢰 할 수 있다.
  • Secret Key 또는 Public/Private Key Pair를 사용하여 서명할 수 있다.

구성

  • 일반적으로 Base64로 인코딩된 데이터 + 전자 서명
  • 데이터 암호화 가능
  • 전자 서명이 되어 있다는 점이 중요.

목적

  • 데이터를 숨기는 것이 아니라 데이터의 신뢰성을 보장하는 것.
    👉 서명된 JWT와 함께 HTTPS를 사용하는 것이 좋다.

인증과정

  • 사용자 측에 사용자의 정보를 관리하는 토큰 기반 인증 메커니즘.
  • 서버에서 세션 정보를 저장하기 위해 세션 스토리지 또는 데이터베이스에 완전히 의존할 필요가 없다.
  • 서버의 확장성과 멀티 기기 및 도메인에서 활용에 이점

1-2. JWT의 구조

JWT의 3대 구성 요소 : Header, Payload, Signature

  • 각 구성 요소는 dot(.)으로 구분

  • JWT의 1번째 구성요소
Header의 구성요소설명
algSignature을 만드는데 사용한 알고리즘 정보
typToken의 타입

예)

// Header
{
    "alg" : "HS256", // 알고리즘: HS256
    "typ" : "JWT"    // Token 타입: JWT
}

Payload

  • JWT의 2번째 구성요소
  • 실질적으로 전달해야 하는 정보
  • Claim: Payload에 담긴 정보 하나 하나를 부르는 명칭
Claim의 종류설명
Registered ClaimsJWT 표준으로 지정된 Claim
Public ClaimsJWT를 사용하는 사람들이 공개적으로 정의하여 사용하는 Claim
기 등록된 Claims와 충돌 방지위해 IANA JSON Web Token 레지스트를 참고하거나 UUID, OID, 도메인 이름 등을 사용
Private ClaimsPublic Claims과 달리 오직 사용자와 서버 사이에서만 합의하여 사용하는 Claim

Registered Claims의 종류

  • 무조건 전부 사용하는게 아니라 상황에 맞게 적절히 사용
  1. iss: 토큰 발급자,
  2. sub: 토큰 제목,
  3. aud: 토큰 대상자,
  4. exp: 토큰 만료시간,
  5. iat: 토큰 발급 시간,
  6. nbf: 토큰 활성화 시간,
  7. jti: JWT의 고유 식별자

예)

{
    "exp": "1245678900", //Registered Claims
    "https://velopert.com/jwt_claims/is_admin": true, //Public Claims
    "user_id" : 12345123 //Private Claims
}

Signature

  • JWT의 3번째 구성요소
  • JWT의 서명 부분
  • Header의 인코딩된 내용과 Payload의 인코딩된 내용을 더한 뒤에 Secret Key와 알고리즘을 이용하여 암호된 값

암호화 방식
: 전달 받은 토큰의 Header와 Payload를 서버의 Secret Key를 이용.

JWT 신뢰성 확인
: 해당 값이 전달 받은 Signature와 같은지 비교.
: 신뢰할 수 없는 토큰은? 👉 서버에서 관리하는 Secret Key가 아닌 다른 Key로 발급한 JWT. Signature가 달라지므로!

예)
HS256(HMAC SHA256) 알고리즘으로 암호화된 Signature

  • Header와 Payload가 합쳐진 내용을 secret과 HMACSHA256을 이용해 암호화.
  • secret을 모른다면 암호화된 Sinature 내용은 확인 불가
HMACSHA256(
    base64UrlEncode(header) + "." + base64UrlEncode(payload),
    secret
)

그룹 Q & A_11.9

메모

JWT에서 암호화하는 부분은 시그니처
just.verify()메소드 하나로 다 열린다.
secrete_key는 gitignore에 저장해주어야 한다!

세션의 단점이 스케일아웃 시 관리가 어렵다. 서버끼리 데이터를 공유하는데 왜 관리가 어려울까요?
👉 컴퓨터서버A에서 서비스 중. 300명 한계인데 15000명 접속자 발생!
-> 해결: 컴퓨터 사양을 늘리거(up)나 여러대를 늘리거나(out)
-> 인터넷을 통해 들어와서 로드밸런싱:
-> 세션을 쓴다는 건 서버에서 세션id를 관리한다는 것
컴퓨터a에서 세션 열려있었는데 로드밸런싱으로 컴퓨터b에 들어가면 세션id 달라서..
->> 해결책: 인메모리 데이터베이스 모든 세션 정보를 통으로 기억하는 데이터베이스를 별도로 쓴다.

api로 하게되면 한쪽 컴퓨터에 몰리게될 경우 문제가 될 수 있음

그래서 토큰을 사용하면 그럴 일이 없어 스케일아웃이 관리 편하다

세션 자체는 휘발성이다(메모리에 저장) expired

브라우저 단에서 체크,분석할 수 있다, 어떤 활동을 했는지도 데이터베이스에 저장

jwt payload에서 registered claims에서
iat는 발급시간은 발급할때마다 다를 거라 자동으로 생성함. 다른 언어(파이썬?자바?)은 그렇지 않을 수도 있다
토큰 만료시간이 없으면? 누군가 토큰을 탈취했을 때 영원히 사용할 수 있게되므로 만료시간이 필요하다

이벤트를 만들 때 몇명이 들어올지 예측하기 어렵다
1만명 유추했더니 12만명이 들어왔다? 어쩔 수 없음..
예) 질병관리청 코로나 사이트
언제 스케일 아웃할까? 인프라 세팅을 해두면 자동으로 스케일 아웃한다
2차 프로젝트 때 docker를 배우게 되는데 disk를 나눈게 아니라 내os위에 다른 os를 띄우는 가상화(=무겁다)
경량화된 버전에 가상화할 수 있는 컨테이너-> 데브옵스 직군의 업무(쿠버네티스 등)
상당한 공수와 기술자가 들어가는데...
지금 쿠버네티스를 배우는 건 추천하지 않음.(나중에~) 쿼리 최적화, 튜닝을 먼저

위코드의 저 자료는 누가 어떻게 ?
공식문서를 봐야 한다! 꼭 보도록 하자!
npm bcrypt
검색어: 'to hash a password', 'hashSync()'
bcrypt.hash()라는 메소드 자체가 프로미스이고 비동기로 동작한다
-> await는 async()안에서만 쓸 수 있다 => 그래서 함수를 별도 선언하면(위코드에 답이 있음)
-> 사고 훈련을 위해 공식문서를 보고 해결하는 방식을 찾아보자
해시값이었으면 3초면 털릴 것을
bcrypt로 비교해서 90일 정도 지나면 털릴 준비가 됐다
그래서 90일 지나면 비밀번호 바꾸라는 경고가 뜨는 것!

const jwt = require("jsonwebtoken");

토큰을 저장하려면 어디에??
로컬스토리지에 저장한다? 쿠키로 보낸다?
세션에 대한 정보를 가지고 -> 무겁다
토큰을 발급한 순간부터 백엔드의 손에서 벗어난다
토큰은 클라이언트가 저장하고 사용한다

profile
검색하고 기록하며 학습하는 백엔드 개발자

0개의 댓글