HTTP의 특성
HTTP는 비연결성 및 무상태성이라는 특징을 가지고 있습니다. HTTP는 요천에 대한 응답을 처리하게 되면 연결을 끊어버리기 때문에 클라이언트에 대한 이전의 상태 정보 및 현재 통신의 상태가 남아있지 않습니다.
서버는 클라이언트를 식별할 수 없다는 단점 또한 존재합니다. 로그인을 하더라도 다음 요청에서 해당 클라이언트를 기억하지 못해 로그인을 해야하는 문제가 발생합니다.
session 기반 인증
1. 유저가 로그인을 한다.
2. 서버에서 계정정보를 읽어 사용자를 확인 후, 사용자의 고유한 ID를 부여하여 세션 저장소에 저장후 세션 Id발행한다.
2. 유저는 해당 session Id를 받아 쿠키에 저장.
3. 인증이 필요한 요청마다 쿠키를 헤더에 실어 보낸다.
4. 서버는 클라이언트가 보낸 Session Id와 서버 메모리로 관리하고 있는 Session Id를 비교하며 Verification 수행한다.
장단점
- 쿠키를 포함한 요청이 외부에 노출되더라도 세션 ID 자체는 유의미한 개인정보를 담고 있지 않습니다.
- 그러나 해커가 이를 중간에 탈취하여 클라이언트인척 위장할 수 있다는 한계가 존재합니다.
- 각 사용자마다 고유한 세션 ID가 발급되기 때문에, 요청이 들어올 때마다 회원정보를 확인할 필요가 없습니다.
- 서버에서 세션 저장소를 사용하므로 요청이 많아지면 서버에 부하가 심해집니다.
JWT 기반 인증
JWT(JSON Web Token)란 인증에 필요한 정보들을 암호화시킨 토큰을 의미합니다.
JWT 구조
Header
Header는 alg과 typ는 각각 정보를 암호화할 해싱 알고리즘 및 토큰의 타입을 지정합니다.
Payload
Payload는 토큰에 담을 정보를 지니고 있습니다. 주로 클라이언트의 고유 ID 값 및 유효 기간 등이 포함되는 영역입니다. key-value 형식으로 이루어진 한 쌍의 정보를 Claim이라고 칭합니다.
Signature
Signature는 인코딩된 Header와 Payload를 더한 뒤 비밀키로 해싱하여 생성합니다. Header와 Payload는 단순히 인코딩된 값이기 때문에 제 3자가 복호화 및 조작할 수 있지만, Signature는 서버 측에서 관리하는 비밀키가 유출되지 않는 이상 복호화할 수 없습니다. 따라서 Signature는 토큰의 위변조 여부를 확인하는데 사용됩니다.
작동과정
- 클라이언트 로그인 요청이 들어오면, 서버는 검증 후 클라이언트 고유 ID 등의 정보를 Payload에 담습니다.
- 암호화할 비밀키를 사용해 Access Token(JWT)을 발급합니다.
- 클라이언트는 전달받은 토큰을 저장해두고, 서버에 요청할 때 마다 토큰을 요청 헤더 Authorization에 포함시켜 함께 전달합니다.
- 서버는 토큰의 Signature를 비밀키로 복호화한 다음, 위변조 여부 및 유효 기간 등을 확인합니다.
- 유효한 토큰이라면 요청에 응답합니다.
장점
- Header와 Payload를 가지고 Signature를 생성하므로 데이터 위변조를 막을 수 있습니다.
- 클라이언트 인증 정보를 저장하는 세션과 다르게, 서버는 무상태가 됩니다.
단점
- 토큰을 탈취당하면 대처하기 어렵습니다.(토큰은 한 번 발급되면 유효기간이 만료될 때 까지 계속 사용이 가능하기 때문입니다.)
보안 전략
- 짧은 만료 기한 설정
- refresh Token
- 클라이언트는 Access Token이 만료되었을 때 Refresh Token을 사용하여 Access Token의 재발급을 요청합니다. 서버는 DB에 저장된 Refresh Token과 비교하여 유효한 경우 새로운 Access Token을 발급하고, 만료된 경우 사용자에게 로그인을 요구합니다.