토큰 Token

  • by

# 토큰 인증 체계는 최근 웹 응용 프로그램에서 자주 사용되는 인증 체계 중 하나입니다.

#등장

– 기존 세션 기반 인증이 갖고 있던 한계를 극복하려고 고안됐다.

– 세션 기반 인증은 서버에서 사용자의 상태를 관리합니다.

따라서 개발자들은 서버의 부담을 줄이기 위해 서버가 사용자의 인증 상태를 저장하는 것이 아니라 클라이언트에 저장하는 방법에 대해 걱정하게 되어 토큰이 등장했다.

– 토큰은 사용자의 인증 상태를 클라이언트에 저장할 수 있고, 세션 인증 방식의 비교에 의해 서버의 부하나 메모리 부족의 문제를 경감할 수 있다.

#토큰

– 무언가를 이용할 수 있는 권한이나 자격을 나타내는 일종의 증표입니다.

– 웹 보안의 토큰은 인증 및 권한 정보가 포함된 암호화된 문자열을 가리킵니다.

이를 사용하여 특정 응용 프로그램에 대한 사용자 액세스 권한을 부여할 수 있습니다.


1. 사용자가 자격 증명이 포함된 서버에 로그인 요청을 보냅니다.

2. 서버는 데이터베이스에 저장된 사용자의 자격 증명을 확인합니다.

3. 인증 성공 -> 해당 사용자의 인증 및 권한 정보를 서버의 개인 키와 함께 토큰으로 암호화한다.

4. 생성된 토큰을 클라이언트에 전달합니다.

HTTP상에서 인증 토큰을 송신하기 위해서 사용하는 헤더인 Authorization 헤더를 사용하거나, 쿠키에 건네주는 등의 방법을 사용한다.

5. 클라이언트는 수신된 토큰을 저장한다.

저장할 위치는 Local storage, Session Storage, 쿠키 등 다양합니다.

6. 클라이언트가 서버에 자원을 요청할 때 토큰을 함께 전달합니다.

토큰을 보낼 때도 Authorization 헤더를 사용하거나 쿠키에 전달할 수 있습니다.

7. 서버는 수신된 토큰을 서버의 개인 키로 확인합니다.

토큰이 위조되었는지 유효기간이 지나지 않았는지 등을 확인.

8. 토큰이 유효한 경우 클라이언트의 요청에 대한 응답 데이터를 보냅니다.

# 토큰 인증 방식의 장점

  • 무상태
    – 서버가 사용자의 인증 상태를 관리하지 않습니다.

    서버는 비밀 키를 통해 클라이언트로부터 전송된 토큰의 유효성을 검증하기만 하면 되므로 무상태 아키텍처를 구축할 수 있다.

  • 확장성
    – 여러 서버가 공통 세션 데이터를 가질 필요가 없다는 점도 토큰 기반 인증의 장점입니다.

    이렇게 하면 서버를 확장할 수 있습니다.

  • 어디서나 토큰 생성 가능
    – 토큰 생성과 검증이 하나의 서버에서 이루어질 필요가 없기 때문에, 토큰 생성만을 담당하는 서버를 구축할 수 있다.

    이를 잘 활용하면 여러 서비스 간에 공통 인증 서버를 구현할 수 있습니다.

  • 승인하기 쉽다
    – 토큰은 인증 상태, 액세스 권한 등 다양한 정보를 담을 수 있기 때문에 사용자 권한 부여에 쉽다.

    이를 활용하여 어드민의 권한 부여나 정보에 액세스할 수 있는 범위도 설정할 수 있다.


#JWT(JSON Web Token)

– 토큰 기반 인증을 구현할 때 대표적으로 사용되는 기술.

– JSON 객체에 정보를 저장하고 이를 토큰으로 암호화하고 전송할 수 있는 기술입니다.

클라이언트가 서버에 요청을 보내면 자격 증명을 암호화된 JWT 토큰으로 제공하고 서버는 이 토큰을 확인하여 자격 증명을 확인할 수 있습니다.

#JWT 구성


1. Header

– HTTP 헤더와 같이 해당 토큰 자체를 설명하는 데이터를 포함합니다.

– 토큰 유형 및 서명을 작성할 때 사용하는 알고리즘을 JSON 형식으로 작성합니다.

{
  "alg": "HS256",
  "typ": "JWT"
}

이 JSON 객체를 base64 방식으로 인코딩하면 JWT의 첫 번째 부분인 header가 완성됩니다.

-base64 방식은, 필요에 따라서 얼마든지 복호 가능한 부호화 방식입니다.

2. Payload

– http의 페이로드와 마찬가지로 전달하려고 하는 내용물을 포함하는 부분이다.

– 어떠한 정보에 액세스할 수 있는지에 대한 권한, 사용자 이름 등의 개인정보, 토큰 발행시간 및 만료일 등의 정보를 JSON 형식으로 포함한다.

{
  "sub": "someInformation",
  "name": "phillip",
  "iat": 151623391
}

이 JSON 객체를 base64로 인코딩하면 JWT의 두 번째 부분인 Payload가 완성됩니다.

3. Signature

– 토큰의 무결성을 확인할 수 있는 부분이다.

– header 와 payload 가 완성되면(자), signature 는 이것을 서버의 비밀열쇠 (암호화에 추가하는 salt)와 header 로 지정한 알고리즘을 사용해 해시한다.

– 누군가가 권한을 속이기 위해 토큰의 Payload를 변조하는 등의 시도를 해도, 토큰을 발행할 때 사용한 비밀을 정확하게 모르면 유효한 시그니처를 만들 수 없기 때문에 서버는 시그니처를 당신은 확인하는 단계에서 틀린 토큰다는 것을 알 수 있다 있다.


# 토큰 인증 체계 제한

-signature를 사용하여 위조된 토큰을 파악할 수는 있지만, 토큰 자체가 탈취되면 토큰 인증 방식의 한계가 밝혀진다.

– 무상태 : 인증상태를 관리하는 주체가 서버가 아니기 때문에 토큰이 탈취되어도 해당 토큰을 강제로 만료할 수 없다.

따라서 토큰이 만료될 때까지 사용자가 스푸핑하여 요청을 보낼 수 있습니다.

– 유효기간 : 토큰이 탈취되는 상황에 대비하여 유효기간을 짧게 설정하면 사용자는 토큰이 만료될 때마다 다시 로그인을 진행해야 하기 때문에 나쁜 사용자 경험을 제공한다.

그렇다고 해서 유효기간을 길게 설정하면 토큰이 탈취되는 경우 보다 치명적으로 작용할 수 있다.

– 토큰 크기: 토큰에 여러 정보를 넣을 수 있는 만큼 많은 데이터를 넣으면 그만큼 암호화하는 과정도 길어지고 토큰 크기도 커지므로 네트워크 비용 문제가 발생할 수 있다.


* 토큰 인증의 한계를 극복하기 위한 대표적인 구현 방법으로 액세스 토큰과 리프레시 토큰을 함께 사용하는 것이다.

#액세스토큰 (Access Token)

– 서버에 액세스하기 위한 토큰.

– 보안을 위해 보통 24시간 정도의 짧은 유효기간이 설정되어 있다.

#리프레시토큰 (Refresh Token)

– 서버 액세스를 위한 토큰이 아닌 액세스 토큰이 만료될 때 새 액세스 토큰을 발행하는 데 사용되는 토큰.

– 새로 고침 토큰은 액세스 토큰보다 긴 수명을 설정합니다.

*이 두 가지 다른 토큰을 사용하는 경우 액세스 토큰이 만료되어도 새로 고침 토큰의 유효 기간이 남아 있으면 사용자는 다시 로그인 할 필요없이 계속 인증 상태를 유지할 수 있습니다.

그러나 새로 고침 토큰은 긴 유효 기간을 가지고 있으며 해당 토큰조차 탈취되면 토큰의 긴 유효 기간 중에 악의가 있는 사용자가 계속 액세스 토큰을 생성하여 사용자의 정보를 해킹할 수도 있기 때문 이다.

이를 위해 새로 고침 토큰을 세션처럼 서버에 저장하고 상태를 관리합니다.

* 결국, 개발자로서 내가 구현하려고 하는 서비스에 어느 인증 방식이 가장 적절한지를 판단해, 의사 결정하는 것을 아는 것이 가장 중요하다.