특정 사용자가 서버에 접근을 했을 때, 이 사용자가 인증된 사용자인지 구분하기 위해서는 여러 방법을 사용할 수 있는데, 대표적인 방법으로는
서버 기반 인증
토큰 기반 인증
이 있고, 상황에 맞는 방법을 선택해서 사용하고 있다.
JWT란 토큰 기반 인증 방법으로, 인터넷 표준 인증 방식이다.
인증을 진행하는 구조는 Cookie와 비슷하지만 다른 점이 바로 서명된 토큰 이라는 점이다. public/private 키를 쌍으로 사용해 토큰에 서명할 경우 서명된 토크는 서버를 통해 이 토큰이 정상적인 토큰인지 인증할 수 있다.
(출처 : https://yuricoding.tistory.com/107)
JWT는 서버와 클라이언트 간 정보를 주고 받을 때 Http 리퀘스트 헤더에 JSON 토큰을 넣은 후 서버는 별도의 인증 과정없이 헤더에 포함되어 있는 JWT 정보를 통해 인증한다.
(이때 사용되는 JSON 데이터는 URL-Safe 하도록 URL에 포함할 수 있는 문자만으로 만든다.)
JWT는 각각의 구성요소가 점(.)으로 구분이 되어있다.
출처 : https://velopert.com/2389
JWT 는 필요한 모든 정보를 자체적으로 지니고 있다. JWT 시스템에서 발급된 토큰은, 토큰에 대한 기본정보, 전달 할 정보 (로그인시스템에서는 유저 정보를 나타내는 정보) 그리고 토큰이 검증됐다는것을 증명해주는 signature 를 포함한다.
typ: 토큰의 타입(JWT)
alg: 해싱 알고리즘. 해싱 알고리즘으로는 보통 HMAC SHA256 혹은 RSA 가 사용되며, 이 알고리즘은, 토큰을 검증 할 때 사용되는 signature 부분에서 사용된다.
{
"typ": "JWT",
"alg": "HS256"
}
Payload 부분에는 토큰에 담을 정보가 들어있다. 여기에 담는 정보의 한 ‘조각’ 을 클레임(claim) 이라고 부르고, 클레임은 key-value 의 한 쌍으로 이뤄진다. 한 토큰에는 여러개의 클레임 들을 넣을 수 있다.
클레임의 세 종류 :
registered 클레임,
public 클레임,
private 클레임
토큰에 대한 정보를 담기 위한 클레임들이며, 이미 이름이 등록되어있는 클레임
공개 클레임들은 충돌이 방지된 (collision-resistant) 이름을 가지고 있어야 합니다. 충돌을 방지하기 위해서는, 클레임 이름을 URI 형식으로 짓습니다.
{
"https://velopert.com/jwt_claims/is_admin": true
}
#3 비공개 (private) 클레임
양 측간에 (보통 클라이언트 <->서버)간에 통신을 위해 협의하에 사용되는 클레임 이름들입니다. 공개 클레임과는 달리 이름이 중복되어 충돌이 될 수 있으니 주의해야한다.
{
"iss": "ajufresh@gmail.com", // 등록된(registered) 클레임
"iat": 1622370878, // 등록된(registered) 클레임
"exp": 1622372678, // 등록된(registered) 클레임
"https://shinsunyoung.com/jwt_claims/is_admin": true, // 공개(public) 클레임
"email": "ajufresh@gmail.com", // 비공개(private) 클레임
"hello": "안녕하세요!" // 비공개(private) 클레임
}
위 예제 payload 는 3개의 등록된 클레임, 1개의 공개 클레임, 2개의 비공개 클레임으로 이뤄져있습니다.
해당 토큰이 조작되었거나 변경되지 않았음을 확인하는 용도로 사용하며, 헤더(header)의 인코딩 값과 정보(payload)의 인코딩값을 합친 후에 주어진 비밀키를 통해 해쉬값을 생성한다.
서명 부분을 만드는 슈도코드(pseudocode)의 구조는 다음과 같습니다.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
이렇게 만든 해쉬를, base64 형태로 나타내면 됩니다 (문자열을 인코딩 하는게 아닌 hex → base64 인코딩을 해야합니다)
1,2,3을 각각 해싱해 합치게 되면 하나의 토큰이 완성된다.
출처 :
https://yuricoding.tistory.com/107
https://velopert.com/2389
https://brunch.co.kr/@jinyoungchoi95/1