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

| Header의 구성요소 | 설명 |
|---|---|
| alg | Signature을 만드는데 사용한 알고리즘 정보 |
| typ | Token의 타입 |
예)
// Header
{
"alg" : "HS256", // 알고리즘: HS256
"typ" : "JWT" // Token 타입: JWT
}
| Claim의 종류 | 설명 |
|---|---|
| Registered Claims | JWT 표준으로 지정된 Claim |
| Public Claims | JWT를 사용하는 사람들이 공개적으로 정의하여 사용하는 Claim |
| 기 등록된 Claims와 충돌 방지위해 IANA JSON Web Token 레지스트를 참고하거나 UUID, OID, 도메인 이름 등을 사용 | |
| Private Claims | Public Claims과 달리 오직 사용자와 서버 사이에서만 합의하여 사용하는 Claim |
Registered Claims의 종류
- 무조건 전부 사용하는게 아니라 상황에 맞게 적절히 사용
- iss: 토큰 발급자,
- sub: 토큰 제목,
- aud: 토큰 대상자,
- exp: 토큰 만료시간,
- iat: 토큰 발급 시간,
- nbf: 토큰 활성화 시간,
- jti: JWT의 고유 식별자
예)
{
"exp": "1245678900", //Registered Claims
"https://velopert.com/jwt_claims/is_admin": true, //Public Claims
"user_id" : 12345123 //Private Claims
}
암호화 방식
: 전달 받은 토큰의 Header와 Payload를 서버의 Secret Key를 이용.
JWT 신뢰성 확인
: 해당 값이 전달 받은 Signature와 같은지 비교.
: 신뢰할 수 없는 토큰은? 👉 서버에서 관리하는 Secret Key가 아닌 다른 Key로 발급한 JWT. Signature가 달라지므로!
예)
HS256(HMAC SHA256) 알고리즘으로 암호화된 Signature
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
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");
토큰을 저장하려면 어디에??
로컬스토리지에 저장한다? 쿠키로 보낸다?
세션에 대한 정보를 가지고 -> 무겁다
토큰을 발급한 순간부터 백엔드의 손에서 벗어난다
토큰은 클라이언트가 저장하고 사용한다