우리는 여러 사이트를 이용할 때 로그인을 하고 사용자 인증을 한 후 정보를 제공받는다.
하지만 우리가 사이트 내에서 이동할 때, 로그인이 유지될 필요가 있는데 이 방법들을 알아보고 왜 jwt라는 것을 이용하는 것에 도달했는지 알아보자.
1. 매번 아이디와 비밀번호로 로그인하기.
클라이언트의 HTTP의 특성 STATELESS. 즉 무상태성을 원칙으로 두기 때문에 아이디와 비밀번호 정보를 저장하지 않는다. 즉 페이지가 이동할 때 마다 아이디와 비밀번호를 서버로 보내는 형식으로 로그인 하는 가장 기초적인 방법이다.
하지만 이는 아이디와 비밀번호를 그대로 보내는 횟수가 많아지면서 스니핑, 스푸핑등의 공격위협에 취약하다.
2. 세션, 쿠키기반 인증
위 로그인의 방법을 해결하기 위해 로그인을 위해 사용자 정보(아이디, 비밀번호)를 한번만 보낼 수 있는 방법이다.
1. 처음 사용자 아이디와 비밀번호로 로그인을 한다.
2. 사용자 인증을 거친 후 회원정보를 이용해 세션을 생성하고 세션DB에 저장한다.
3. 세션 ID를 이용자에게 발급후 응답한다.
4. 그 세션ID정보를 클라이언트에서 쿠키형태로 저장한다.
5. 이후 클라이언트는 아이디,비밀번호가 아닌 쿠키로 로그인을 처리하게 된다.
하지만 이 방법에도 문제점이 있는데,
1) 사용자정보를 저장하지 않는 stateless하지 않다.
2) 쿠키를 탈취당하면 id와 비밀번호를 탈취당한 것과 같아, 서버에서 정보를 제공받을 수 있다.
3) scale-out시 세션저장소도 같이 늘어나므로 추가적인 저장공간이 필요하다.
4) 저장공간이 늘어나면서 부하가 늘어난다.
3. 토큰 기반 인증(JWT)
토큰기반 인증중 가장 대표적인 것은 JWT(JSON WEB TOKEN)이다.
JWT토큰은 위사진의 왼쪽처럼 인코딩된 문자열로 보여진다.
이 긴 문자열은 세가지로 나눠지는데,
1) HEADER : 암호화 알고리즘 방식, 타입 등의 메타데이터.
2) PAYLOAD : 인증된 유저의 정보가 들어가는 부분.
3) SIGNATURE : 헤더와 페이로드의 암호화된 부분.
이렇게 되어 있다.
HEADER와 PAYLOAD는 JSON문자열을 BASE64방식으로 인코딩 되어 이루어진다.
그리고 SIGNATURE은 이 인코딩된 문자열을 HEADER에서 지정된 암호화 알고리즘과 지정된 KEY값으로 encryption된다.
JWT = Encoded Header + "." + Encoded Payload + "." + Verify Signature
1. 아이디와 비밀번호로 로그인 요청을 한다.
2. DB에 저장된 회원인지 확인한다.
3. JWT로 Access토큰을 발급한다.
4. 클라이언트로 jwt를 응답한다.
5. JWT로 데이터를 요청하고 서버에서 검증 후 데이터를 제공한다.
JWT의 Verify Signature을 만든 key는 서버만이 가지고 있으므로, decryption후 header, payload와 다르다면, 적절하지 않은 토큰이라고 판단 할 수 있다.
또한 쿠키-세션방식처럼 별도의 저장소를 필요로 하지 않으므로 저장공간에 있어서 효율적이다.
하지만 토큰 방식에도 몇가지 문제점이 있는데,
1) 토큰이 한번 발급되면 따로 삭제하는 방법이 없으므로 발급된 이후 악의적으로 사용되는 것에 있어서 제한을 할 수 없다.
=> refresh Token과 exp(만료시간)을 둠으로써 Access토큰의 만료시간이 지나면 사용할 수 없게 하고 refresh토큰으로 재발급 받을 수 있게 한다.
2) payload부분에는 사용자 정보가 들어가는데 단순히 base64로 인코딩된 것이기 때문에 탈취만 하면 정보를 마음대로 볼 수 있다. 때문에 payload부분에 민감한 데이터 예를들어 비밀번호같은 정보는 넣을 수 없다.
'서버 > 서버' 카테고리의 다른 글
인증) OAuth 2.0 - 카카오인증 실습(feat. postMan) (0) | 2020.09.15 |
---|---|
REST / REST API / RESTful (0) | 2020.08.14 |
Query string vs Path Variable (0) | 2020.08.13 |
HTTP (0) | 2020.08.13 |
API (0) | 2020.08.13 |