HTTP 200 OK

Memento mori & Carpe diem

CS

JWT 토큰이란

sjoongh 2022. 5. 28. 15:10

Authentication

로그인 인증 구현 방식에는 session cookie 방식과 jwt토큰 방식이 존재한다. session cookie 방식은 사용자에 따라서 고유의 session ID가 발급되며 유의미한 정보를 담고 있지 않기 때문에 쿠키방식보다는 안전하지만, 세션저장소에 모두 담아두기 때문에 다수의 요청이 발생시 부하가 발생할 수 있다.

 

JWT

세션쿠키와 하게 인증에 필요한 정보들을 암호화한 토큰을 사용한느 방식으로 비밀키가 유출되지 않는 이상 토큰을 복호화 하지 못하므로 보안이 유리하다. access token의 기한은 유효하지만 access token이 만료되기 전에 사용자가 로그인하면 refresh token을 이용해서 access token을 재발급하여 사용기한을 늘릴 수 있다. refresh token이 만료되면 재로그인 요청을 보낸다. 그러나, 이 또한 세션쿠키보다 길이가 길기 때문에(.을 기준으로 세가지 부위로 나뉨) 인증요청이 많아질수록 네트워크 부하가 심해질 수 있다.

 

Generate Token

토큰을 생성할 때는 요청에 토큰이 있는지 확인하고 없다면, 유저의 로그인 정보(아이디, 패스워드)를 받아서 이를 이용해서 토큰을 생성해놓고 유효한 정보인지를 확인한 후에 유효한 로그인 정보일 경우에 생성한 토큰을 돌려준다.

 

Validate Token

유효성 검사는 토큰을 헤더로 받아서 토큰을 해부해서 유효한 로그인 정보인지를 검사한 후에, 토큰이 유효하다면 요청을 처리한다.

 

세션 : 세션의 경우 사용자의 인증 정보를 서버측 메모리에 저장하게 된다. 다양한 저장방법이 있지만 문제는 서버측의 자원을 사용한다는 것이다. 이때 사용자가 적을경우에는 문제가 없지만 사용자가 점차 증가하게 된다면 서버측 메모리(자원)들이 부족하게 된다. 이 문제를 해결하기 위해서는 서버의 확장 및 업그레이드가 필요하다. 각각 스케일 아웃, 스케일 업이라고 한다.

 

토큰기반 인증 : Stateless 서버의 경우 사용자의 요청이 이전 요청과 어떠한 관계와 종속이 되지 않는 서버를 의미한다. 토큰 기반 인증은 stateless서버에 적합하다.

 

토큰에는 크게 두가지 종류가 있다 바로 Claim, Oauth이다.

 

Oauth : 인증과정을 통해 발급되는 토큰의 경우에는 Random String으로 특별한 정보를 가지고 있지 않는것이 일반적이다. 따라서 서버에서는 이 토큰을 이용하여 다시 관련된 정보를 찾아야 한다.

 

Claim Token의 경우에는 토큰 자체에 필요한 정보들이 담겨있는 것으로 JWT가 대표적이다

 

JWT는 Json형태를 띄는 Token으로 필요한 모든 정보를 가지고 있다. 이는 Http Header에 넣어 전달 할 수 있으며 URL 파라미터로도 전달이 가능하다.

 

JWT 장점

 

자가수용적 : JWT는 필요한 모든 정보를 자체적으로 지니고 있기 때문에, 서버에서 클라이언트의 정보를 저장 및 관리할 필요가 없다.

 

안정성 : JWT에는 Sign정보가 담겨있기 때문에, 보낸이가 바뀌었는지, 정보가 바뀌었는지를 검증할 수 있다.

헤더에는 두가지 정보가 담겨 있다. typ(토큰 타입), alg(해시 알고리즘)이다. typ는 토큰의 타입(JWT)를 알려주며 alg는 해시 알고리즘을 정한다.

 

인증/인가 : JWT를 사용하는 가장 보편적인 방법이다. 사용자가 로그인하면 이후 모든 요청에 JWT토큰을 헤더에 담아 인증할 수 있다. JWT를 이용하면 해당 토큰으로 허용되는 경로, 서비스, 리소스에 접근할 수 있다. 오버헤드가 적고 여러 도메인에서 쉽게 사용할 수 있어 가장 많이 사용한다.

 

정보 교환 : 당사자 간 정보를 안전하게 전송하는 방법이다. 공개/개인 키 쌍을 이용해서 JWT에 서명할 수 있기 때문에 발신지를 파악할 수 있다. 헤더와 페이로드를 사용해서 시그니처를 계산하기 때문에 콘텐츠의 변조 여부도 확인 가능

JWT는 Header, Payload, Signature의 세 부분으로 이루어지고 '.'을 사용해서 구분된다.

 

Header : JWT라는 타입, 암호화 할 알고리즘 종류를 담고 있다.

Payload : 사용자, 추가 데이터에 대한 정보를 포함한 클레임을 표현한다. 클레임에는 registered/public/private의 세 종류가 있다. 각각은 다음과 같은 정보를 담고 있다.

- Registered Cliam : iss(issuer), exp(expiration time), sub(subject), aud(audience)

- Public Claim : 공개용 정볼르 위한 사용자 정의 클레임

- Private Claim : 서버/클라이언트 간 정보 공유를 위한 맞춤형 클레임

 

Signature를 만들기 위해서는 인코딩된 헤더와 페이로드, 헤더의 알고리즘이 필요하다. 이는 메시지의 변경 여부를 확인할 수 있고, 개인키로 서명된 토큰의 경우 발신인도 구분할 수 있다.(헤더와 페이로드의 값은 Base64이다)

 

JWT의 실제 사용

 

인증을 구현할 때 사용자가 로그인을 하면 Access Token을 반환한다. 일반적으로 토큰의 만료 시간은 짧게 잡는 것이 좋고, 민감한 데이터를 브라우저에 저장하면 안된다.

생성된 토큰은 헤더에 포함되어 Authorization의 value로 사용되고 앞에는 주로 Bearer가 붙는다.

 

서버는 Authorization헤더에 유효한 jwt가 있는지 확인하고 jwt가 있는 경우 토큰을 검증해서 보호된 리소스에 엑세스할 수 있는 권한을 부여한다. 또한 이 헤더로 전송된 토큰은 쿠키를 사용하지 않아 CORS로부터 안전하다.

 

Signature : 인코딩된 헤더와 페이로드, 헤더의 알고리즘이 필요하다. 이는 메시지의 변경 여부를 확인할 수 있고, 개인키로 서명된 토큰의 경우 발신인도 구분할 수 있다.

 

Encoding과 Encryption의 차이

 

Encoding : 시스템에서 사용할 수 있도록 데이터를 적절하게 (그리고 safely하게) 변형하는 것이다. Encoding의 목적은 정보를 숨기는 것이 아니라 오히려 정보를 적절하게 사용하도록 하는 것이다. 그래서 Encoding은 key가 필요없고 encode하기 위한 알고리즘만 필요하다 --> ascii, unicode, url encoding, base64

 

Encryption : 다른 누군가로부터 데이터를 비밀스럽게 지키기 위해 데이터를 변형하는 것이다. 예를 들어 누군가에게 비밀편지를 준다던지, 인터넷으로 password를 준다던지 그래서 사용성에 focusing을 한것이 아니라 사용이 허가되지 않은 사람들이 데이터를 사용하지 못하도록 하려는 목적을 가지고 있다. 그래서 Encryption을 하기 위해서는 평문(plain text), 암호 알고리즘(cipher algorithm), key가 필요하다 --> aes, blowfish, rsa

 

HS256( HMAC SHA-256 ) : 1개의 secret key를 공유하는 대칭 암호 알고리즘
RS256(RSASSA SHA-256): : 비밀키/공개키 2개의 key를 공유하는 대칭 비암호 알고리즘
ES256(ECDSA P-256 curve SHA-256)
*뒤에 숫자는 key의 bit수를 나타내는 것이다.

'CS' 카테고리의 다른 글

WebFlux  (0) 2022.11.06
pinPoint  (0) 2022.11.06
SSR과 CSR 의 차이  (0) 2022.02.22
yarn이란?  (0) 2022.01.19
vue와 react 설치방법  (0) 2022.01.13