Session / Token(JWT)(2)

홍석진·2021년 9월 23일
0

Back-End

목록 보기
2/3
post-thumbnail

📙토큰과 JWT

토큰(Token)

토큰은 정말 많은 곳에서 사용되는 용어입니다. 그래서 정의내리기 어렵고 사용하는 곳에 따라 의미도 조금씩 달라져서 데이터토큰(문자열)에 대한 설명을 한번 읽어보시면 도움이 되실 것 같습니다. 5.링크 의 이미지를 참조해서 토큰 기반 인증시스템을 설명 드리겠습니다.

위 그림은 로그인 시에 서버와 클라이언트 간에 토큰을 사용한 인증 과정을 보여줍니다. 토큰 기반 인증의 장점은 Session / Token(JWT)(1)에 세션과 비교하는 부분에서 설명드렸습니다. 이러한 토큰 인증 시스템에서 주로 사용하는 JWT에 대해서 본격적으로 설명드리겠습니다.


JWT(Json Web Token)

jwt.io에서 설명하는 JWT(Json Web Token)는 당사자 간에 정보를 JSON개체로 안전하게 전송하기 위한 간결하고 자체 포함된 방법을 정의하는 개방형 표준(RFC 7519)입니다. 쉽게 말하면 클라이언트와 서버, 서비스와 서비스 사이 통신 시 권한 인가(Authorization)를 위해 사용하는 토큰입니다. URL에 대해 안전한 문자열로 구성되어 있어 HTTP의 어디든(URL, Header,...)에 위치할 수 있습니다. JWT는 Claim 기반의 Web Token입니다. Claim 기반에 대한 설명은 1.링크 를 읽어보시면 도움이 되실 것 같습니다.

구조와 생성

구조

Header.Payload.Signature

헤더(Header), 페이로드(Payload), 서명(Signature) 이 세 부분을 점(.)으로 구분하는 구조입니다.

JWT를 검증하는데 필요한 정보를 가진 JSON 객체는 Base64 URL-Safe로 인코딩된 문자열입니다. 헤더는 JWT를 어떻게 검증(Verify)하는가에 대한 내용을 담고 있습니다.

{
	"alg": "HS256",
 	"kid": "key ID"
}

여기서 alg는 서명시 사용하는 알고리즘이고, kid는 서명시 사용하는 키(Public, Private key)를 식별하는 값입니다. 위와 같은 JSON 객체를 문자열로 직렬화하고 UTF-8과 Base64 URL-Safe로 인코딩하면 다음과 같이 헤더를 생성할 수 있습니다.
HS256 :

HS256 는 HMAC SHA256 의 줄임말이고 HAMC은 Hash-based Message Authentication Code 라는 뜻을 가진다.
해싱에 대해서 다시 얘기해볼 때 입력값이 같다면 해싱된 해시값은 항상 동일하기 때문에 수정에 대한 검출은 가능하지만 거짓 행세하는 것을 검출하기는 어렵다.
거짓행세에 대해 검출하고 차단하기위해 SHA256으로 해싱된 메세지를 메세지 인증 코드(private key <- 추측임..)로 암호화(서명) 하여 송신하고 수신측에서는 동일하게 소유한 private key로 복호화 및 서명을 검증하는 방식이다. 동일하게 소유했다는것은 즉, HMAC SHA256 알고리즘이 대칭키 방식임을 알 수 있다.

Base64URLSafe(UTF-8('{"alg": "HS256","kid": "Key ID"}')) -> eyJhbGciOiJIUzI1NiIsImtpZCI6ImtleSBJRCJ9

Payload

Payload 또는 Body는 JWT의 내용입니다. 페이로드(Payload)에 있는 속성들은 클레임 셋(Claim Set)이라고 부릅니다. 클레임 셋은 JWT에 대한 내용(토큰생성자(클라이언트)의 정보, 생성 일시 등)이나 클라이언트와 서버 간 주고 받기로 한 값들로 구성됩니다.

{
	"name": "seokjin.hong",
	"iat": "1516239022"
}

위와 같은 JSON 객체를 문자열로 직렬화하고 Base64 URL-Safe로 인코딩하면 다음과 같이 페이로드를 생성할 수 있다.

Base64URLSafe('{"name": "seokjin.hong","iat": "1516239022"}') -> eyJuYW1lIjoic2Vva2ppbi5ob25nIiwiaWF0IjoxNTE2MjM5MDIyfQ

Signature

점(.)을 구분자로 해서 헤더와 페이로드를 합친 문자열을 서명한 값입니다. 서명(Signature)은 헤더의 alg에 정의된 알고리즘과 비밀 키를 이용해서 생성하고 Base64 URL-Safe로 인코딩 합니다.

JWT 디버거를 이용한 사진입니다.

Encoded 부분에 인코딩된 Header.Payload.Signature(JWT)이 완성이 됩니다.

암호화에 대한 명세는 JWT 하위 JWS(JSON Web Signature)와 JWE(JSON Web Encryption)에 되어 있습니다. 저도 글을 6.링크 에서 JWT에 대한 구현을 살펴보았는데 JWT생성과 검증 관련해서는 여러가지 api들이 있다고 합니다. JWT 생성 검증과 관련된 코드 gist 를 참고해서 한번 구현해봐야 겠습니다. 알고리즘에 대해서도 공부할 것이 많고 보안과 암호화에 대해서도 많은 공부가 필요할 것 같습니다. JWT는 API쪽과 웹 서버쪽 둘다 유용한 것 같습니다. 이렇게 정리하면서 세션 방식이 오래되었고 이제는 JWT가 더 좋다라고 생각할 수 있지만 안정성이 추구되는 웹에서는 세션이 훨씬 안전하고 효율적일 수 있을 것 입니다. 상황에 따라 최적의 유용한 기술들을 사용하는 것이 좀 치는 개발자가 되는 길이라고 생각이듭니다. 불편한 걸 못참는 것이 개발자의 덕목이라고 생각합니다. 많은 방법들과 알고리즘을 공부해서 상황에 따라 생각할 수 있는 폭을 넓혀야겠습니다.


참고 링크
1. Claim 기반이란
2. 데이터 토큰에 대한 설명
3. JWT 정확하게 무엇이고 왜 쓰이는 걸까
4. JWT 이해하기
5. 토큰 기반 인증 VS 서버 기반 인증
6. JWT를 소개합니다
7. RS256, HS256 차이

profile
질문이나 의견이 있으시면 남겨주세요. 서로의 발전이라고 생각합니다.

0개의 댓글