목차
📌 Token
: 클라이언트가 서버에 접속을 하면 서버에서 클라이언트에게 해당 클라이언트에게 인증이되었다는 의미로 토큰을 부여함
- 예를 들어, 놀이공원 입장시 개인마다 주는 입장권을 손님에게 주고 개인(클라이언트)이 관리하게 함
- 토큰은 세션과는 달리 서버가 아닌 클라이언트가 직접 관리하기 때문에 서버의 부담을 덜 수 있음
- 앱과 서버가 통신 및 인증할때 가장 많이 사용이 됨
📍 서버 기반과 토큰 기반의 차이
서버(세션)기반
서버 측에서 사용자의 인증 정보를 관리함
클라이언트의 요청에 따라 클라이언트의 상태를 계속해서 유지해놓고 사용하게 됨
이렇게 되면 사용자가 증가하면서 성능의 문제가 발생되어 확장성이 어렵다는 단점이 있음
토큰 기반
위의 세션 단점을 극복하기 위해서 나온게 토큰!
토큰은 사용자(클라이언트)가 관리를 하고 로그인이 필요한 경우 헤더에 토큰을 함께 보내 인증받은 사용자인지 서버에서 확인을 함
서버와 다르게 상태를 유지하므로 상태성을 가짐
Token 인증 방식
- 클라이언트가 로그인을 한다.
- 서버에서는 클라이언트에게 토큰을 발급한다.
- 클라리언트에서는 서버에서 전달받은 토큰을 쿠키나 스토리지에 저장하고, 서버에 요청을 할때마다 해당 토큰을 요청 헤더에 포함하여 전달한다.
- 서버는 요청이 올때마다 토큰을 확인하고 요청에 응답한다. 토큰에는 사용자의 정보가 담겨있기 때문에 따로 DB에 정보 확인 요청을 보내지 않아도 된다.
[예시]
Token 방식의 단점
- 쿠키/세션과 다르게 토큰 자체의 길이가 길어, 인증 요청이 많아질수록 네트워크 부하가 심해짐
- Payload 암호화가 되지 않기 때문에 유저의 중요 정보를 담을 수 없음
- 토큰을 탈취당하면 대처가 어려움 -> 사용 기간 제한 설정으로 극복해야 함
📌 JWT(JSON Web Token)
: JSON 객체에 정보를 담고 이를 토큰으로 암호화하여 전송
- JWT는 JSON 데이터를 Base64 URL-safe Encode를 통해 인코딩하여 직렬화한 것이며, 디코딩도 가능/ 비밀번호와 같이 노출되어서는 안되는 민감한 정보를 담지 않도록 해야함
- Header : 해당 토큰 자체를 설명하는 데이터가 담겨 있음/ 토큰의 종류, 시그니처를 만들때 사용할 알고리즘을 JSON 형태로 작성함
{
"alg" : "HS256",
"typ" : "JWT"
}
- Payload : 서버와 클라이언트가 주고 받는 시스템에서 실제로 사용될 정보에 대한 내용을 담고 있음/ 접근권한, 유저의 이름, 개인정보, 토큰의 발급 시간 및 만료 시간등의 정보를 JSON 형태로 담음
{
"sub" : "12345678",
"name" : "John Doe",
"iat" : 1516239022
}
- Signature : 토큰의 무결성을 확인하는 부분/
- 시그니처의 구조는 (헤더+페이로드)와 서버가 갖고 있는 유일한 Key 값을 합친 것을 헤더에서 정의한 알고리즘으로 암호화함
📍 Header와 Payload는 단순히 인코딩된 값이기 떄문에 제 3자가 복호화 및 조작할 수 있지만, Signature는 서버측에서 관리하는 비밀키가 유출되지 않는 이상 복호화할 수 없다. 따라서 Signature는 토큰의 위변조 여부를 확인하는데 사용됨
Access Token과 Refresh Token
- Access Token : 서버에 접근하기 위한 토큰으로 토큰과 비슷한 역할을 하며, 보안을 위해 24시간 정도 짧은 유효기간으로 설정됨
- Refresh Token : 서버 접근을 위한 토큰이 아닌 액세스 토큰이 만료되었을때 새로운 액세스 토큰을 발급받기 위해 사용되는 토큰 액세스 토큰보다 긴 유효기간으로 설정