텍스트 기반의 통신규약으로 비연결성(Connectionless)와 무상태성(Stateless)을 특징으로 지닌다. 즉, 클라이언트 측의 요청이 서버에 닿아, 서버가 응답을 마치면 기록이나 연결을 끊어버리게 된다. 어쩌면 당연한 것이, 수억명의 유저의 활동을 기억하게 되면 상당한 자원 낭비를 피할 수 없으니 말이다.
그러나 HTTP의 특징은 다른 말로 서버가 클라이언트를 식별하지 못하게 된다는 것이다. 단적으로 로그인을 하더라도 해당 클라이언트를 기억하지 못하게 되는 것처럼 말이다.
이러한 HTTP의 결점은 Cookie와 Sesstion을 통해 보완된다.
쿠키는 클라이언트가 특정 웹사이트에 방문해 서버에 요청을 보낼 때, 서버의 응답과 함께 그 응답에 관한 정보를 담은 작은 텍스트 파일이다. 이후 클라이언트의 또다른 요청이 수행될 때 서버 측으로부터 받은 쿠키를 동봉?함으로써 특정 클라이언트의 정보를 전달한다. 쉽게 말하자면 놀이동산 매표소에서 자유이용권을 구매하고 각각의 놀이기구를 타기 전에 해당 자유이용권을 통해 자격을 확인받는 것과 비슷하다.
하지만 이러한 방식은 몇몇 단점을 지니게 되는데, 요청 시 쿠키의 값을 그대로 보내기 때문에 유출 및 조작의 위험이 동반된다. 또한 쿠키는 용량 제한이 있어 많은 정보를 담을 수 없고, 쿠키의 정보량이 커지면 네트워크의 부담을 초래한다.
쿠키의 유출 및 조작의 위험으로 비밀번호와 같은 인증정보를 쿠키에 담아 열린 공간인 HTTP에 전달하는 것은 상당히 위험하다.
그래서 세션은 동일하게 클라이언트의 요청에 대한 응답으로 쿠키를 이용하지만, 유출되면 안되는 인증정보는 따로 서버에 저장해 쿠키에는 클라이언트 식별자인 JSESSIONID(쉽게는 이름표?)를 함께 담아 보낸다.
그래서 쿠키가 유출이 되더라도 클라이언트 인증정보는 빈껍데기인 JSESSIONID로만 남아있어 해커가 유의미한 정보를 탈취할 수 없게 된다.
그러나 클라이언트마다 새로운 고유 세션ID를 발급하고 요청마다 JSESSIONID를 통해 식별해야 하기때문에 요청이 폭주하면 서버의 부하가 심해진다.
그렇다면 쿠키처럼 간편하게 사용되지만 해킹의 위험이 적고, 세션처럼 안전하지만 서버에 인증정보를 저장하지 않는 인증 방식은 없을까?
그것이 JWT 기반 인증이다. JWT(JSON Web Token)란 인증에 필요한 정보들을 암호화시킨 토큰으로 쿠키와 세션 방식과 유사하게 HTTP 헤더에 실어 서버가 클라이언트를 식별한다.
클라이언트에서 로그인 요청을 보내면 서버는 해당 유저 정보를 토큰에 담고 이 위에 사인해서 전달한다. 이 후 또다른 요청과 함께 사인된 토큰이 도착하면 서버는 그 사인이 유효한지 검증 후 응답을 보내게 된다.
JWT에서 서버가 하는 일은 그 토큰이 유효한지 아닌지 식별하는 것일뿐이다.
카카오톡 QR코드가 대표적인 예이다.
JWT는 .을 구분자로 header.payload.signature로 구성된 조합이다.
{
"alg": 'HS256",
"typ": 'JWT'
}
Header는 alg과 typ은 각각 정보를 암호화할 해싱 알고리즘 및 토큰의 타입을 지정합니다.
{
"sub": '1234567899",
"name": 'John',
"iat": 1234532532
}
Payload는 토큰에 담을 정보를 지니고 있다. 주로 클라이언트의 고유 ID 값 및 유효 기간 등이 포함되는 영역이다.
Signature
Signature는 인코딩된 Header와 Payload를 더한 뒤 비밀키로 해싱하여 생성한다.
Header와 Payload는 단순히 인코딩된 값이기 때문에 제 3자가 복호화 및 조작할 수 있지만, Signature는 서버 측에서 관리하는 비밀키가 유출되지 않는 이상 복호화할 수 없습니다. 따라서 Signature는 토큰의 위변조 여부를 확인하는데 사용됩니다.
인증 과정
https://www.youtube.com/watch?v=tosLBcAX1vk
http://www.opennaru.com/opennaru-blog/jwt-json-web-token/
https://lovefor-you.tistory.com/247