1. JWT란?
- JWT(Jason Web Token)는 웹에서 사용하며, Jason 데이터 구조로 정보를 전달하는 토큰에 관한 표준 규격이다.
- 사용자의 인증(authentication) 또는 인가(authorization)를 포함한 모든 정보를 한 객체에 담아서 전달한다.
- 따라서 세션 ID로 매번 사용자 정보를 서버에서 조회해야하는 세션과는 달리,
JWT는 토큰 자체에 정보가 있으므로 서버는 토큰만 검증해주면 된다.
[토큰의 장점과 단점 링크]
- 비대칭 암호화 알고리즘을 사용하는 토큰형 인증 방식이다.
2. JWT의 구조
- JWT는 헤더(Header), 페이로드(Payload), 서명(Signature)으로 구성되어 있다.
- 각각은 .(Dot)인 구분자로 나누어 전체를 이루고 있다.
- 아래는 완성된 토큰의 예시이다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlNTQVJBTkdIQUUhISEiLCJpYXQiOjE1MTYyMzkwMjJ9.nHAK4-S134nf4iopvfRQ7qv1IXD_cMUqbYf33BeCeIU
[토큰 만들어보기]
👀 잠깐!>_<
JSON 파일 구조
- JSON은 사람이 읽을 수 있는 텍스트를 사용하여 데이터를 저장하고 전송 하는 개방형 표준 파일 형식이다.
- JSON 파일은 .json 확장자를 사용한다.
- JSON 데이터는 키(Key)와 값(Value)의 쌍으로 저장된다.
- Array : 대괄호[ ]로 묶인 값
[ "사과는", "오이시", "오이시는", "바나나" ]
- Object : 중괄호{ }로 묶인 키와 값의 쌍
{"name": "송해", "age": 3, "favoriteSport": "Tottenham Zzang"}
{
"alg": "HS256",
"typ": "JWT"
}
- 헤더에서는 토큰의 유형과 서명 알고리즘 정보가 저장된다.
- JSON은 글자를 3글자로 줄이는 경향이 있는데 이는 JWT 토큰이 네트워크로 전달될 때 공간을 적게 차지하기 위해서이다.
2) 페이로드(Payload)
{
"sub": "1234567890",
"name": "SSARANGHAE!!!",
"iat": 1516239022
}
- 페이로드에서는 서버와 클라이언트 사이에 오가는 실제 데이터를 가지고 있다.
- Key를 Claim이라고 부른다.
- Base64로 인코딩이 된 파트이며, 온라인디버거를 통해서 쉽게 디코딩하여 데이터 열람이 가능하다.
따라서, 패스워드 같은 결정적인 정보들은 페이로드(Payload)에 담기면 안된다.
- Claim에는 3가지 종류가 있다.
1. registered claim (등록된 클레임)
- 이미 정해진 종류의 데이터
- 사용이 권장되는 클레임
- 보통 3글자로 쓰인다
- ex) "sub", "name", "iat"
- 아래 <JWT에서 자주 쓰이는 JSON 키> 참고
- [그외 클레임 종류]
2. public claim (공개 클레임)
- 사용자가 직접 지정한 클레임
- 충돌 방지를 위해서 ⑴URI 포맷 사용
{
"https://naver.com": true
}
3. private claim (비공개 클레임)
"state": "drowsy"
<JWT에서 자주 쓰이는 JSON 키>
- sub 키: 인증 주체(subject)
- iss 키: 토큰 발급처
- typ 키: 토큰의 유형(type)
- alg 키: 서명 알고리즘(algorithm)
- iat 키: 발급 시각(issued at)
- exp 키: 말료 시작(expiration time)
- aud 키: 클라이언트(audience)
3) 서명(Signature)
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)
- 서명(signature) 정보를 통해서 위변조 여부를 빠르게 검증할 수 있다.
- base64UrlEncode(header) : Header 디코딩한 값
- base64UrlEncode(payload) : Payload 디코딩한 값
- your-256-bit-secret : 위 두 개를 합치고, 서버가 가진 개인키(secret)로 암호화 되어있는 상태
- secret은 서버만 알고 있다. 따라서 header와 payload를 수정한 후 signature를 다시 만들 수 없다.
3. JWT의 동작 원리
1. 사용자 로그인
2. 서버(백엔드)에서 DB 에서 사용자 확인
3. 권한 인증 정보를 PayLoad에 넣고 JWT 발급
4. 생성한 JWT 토큰을 클라이언트(프론트)에 반환하고 클라이언트는 이 토큰을 저장
5. 클라이언트가 데이터 요청을 할 때 Header에 다가 토큰을 실어 보냄
6. Header의 토큰을 검증하고, Payload의 값을 디코딩하여 사용자의 권한을 확인
7. 데이터 반환(응답)
4. 비대칭키와 JWT
- JWT에서는 기본적으로 공개키(비대칭키) 암호화 방식을 사용한다.
- 비대칭키에는 (A: 공개키, B: 비밀키) 두 가지 키가 있다.
- 비밀키(B)는 서버만 가지고 있고, 절대 공개하지 않는다.
- 공개키(A)는 공개되어 있어서, 누구든 쉽게 이 키를 구할 수 있다.
- 비밀키(B)가 있는 곳에서만 Signature을 생성한다.
공개키(A)로만 Signature을 해석할 수 있다.
- 복호화한 결과가, JWT 속 header, payload와 일치 한다면, 이 JWT가 위조 되지 않았음이 증명된다.
주석
⑴ URI : NameSpace는 URI로 표현된다. URI는 인터넷 상 자원을 구분하기 위한 문자열 구성이고 URL을 포함하는 개념이다.
* NameSpace : 동일한 element일 때, 충돌이 발생하고 어느 element가 사용자가 원하는 데이터인지 알 수 없다.
따라서 element와 속성이름을 고유하게 구분하기 위해서 NameSpace를 만들었다.
* URL : URI의 한 형태로, 인터넷 상의 자원의 위치와 식별자이다.
참고자료
JWT 그림
: https://blog.soomgo.com/blog/jwt-for-all/
: https://medium.com/@extio/understanding-json-web-tokens-jwt-a-secure-approach-to-web-authentication-f551e8d66deb
JWT 설명
: https://velog.io/@vamos_eon/JWT%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94%EA%B0%80-1
: https://www.daleseo.com/jwt/#google_vignette
JSON
: https://docs.fileformat.com/ko/web/json/
URI/URL
: https://taehoon95.tistory.com/49