사용자를 인증(Authentication)하는 방법

binarycastle·2020년 6월 9일
0

인증 방식

서버 - 클라이언트 환경에서 HTTP 통신 시 사용자를 인증하는 방법은 크게 세션 기반, 그리고 토큰 기반의 두 가지로 나뉜다.

JWT(Token)

JWT Token은 Header, Payload, 그리고 Signature로 이루어진 문자열을 Base64로 encoding한 문자열의 형태를 가진다.
토큰의 각 파트는 순서에 맞춰 아래와 같이 .으로 구분되어 연결된다.

xxxxxx.yyyyyy.zzzzzz

각 파트의 역할은 아래와 같다.

  • Header:
    암호화 알고리즘과 토큰의 타입을 정의한다.
{ "alg": "HS256", "typ": "JWT" }
  • Payload:
    Claim으로 불리는 토큰에 담을 추가적인 데이터를 정의하는 곳이다.
    Header와 마찬가지로 암호화되어 있지 않기 때문에 Base64로 디코딩하면 데이터를 그대로 볼 수 있다.
    따라서 패스워드와 같은 크리티컬한 정보를 담으면 안 된다.
{ "iat": 1590766090, "name": "binarycastle", "admin": true }
  • Signature:
    토큰 값이 외부에 의해 변경되지 않고 유효한지 검증할 수 있는 서명이 담겨있다.
    서명은 Header와 Payload를 .으로 연결한 문자열과 비밀 키(secret)를 Header에 정의한 알고리즘으로 암호화하여 생성한다.
    secret이 노출되면 외부에서도 토큰을 생성하는 게 가능해지기 때문에 서버에서 안전하게 보관해야 한다.
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

그리고 토큰은 그 역할에 따라 Access token과 Refresh Token으로 나뉜다.

  • Access token:
    서버로 request 시마다 HTTP header에 담아 전송하는 토큰이다.
    모든 요청에 담겨지기 때문에 외부에서 해당 통신을 도청한다면 토큰을 탈취당할 가능성이 있다.
    따라서 토큰을 탈취당하더라도 피해를 최소화하기 위해 Access token의 만료 기간은 짧게 설정하는 것이 좋다.

  • Refresh token:
    위와 같은 Access token의 한계를 보완하기 위해 Refresh token이 존재한다.
    Refresh token은 오직 Access token 만료 시에 새로운 Access token을 발급받을 때만 사용된다.
    Refresh token을 담아 서버로 Access token 재발급 요청을 하면 서버에서는 새로운 Access token과 새로운 Refresh token을 생성하여 반환한다.
    Refresh token은 일회성으로 사용되고 버려지기 때문에 탈취당할 가능성이 적다.
    따라서 만료 기간을 Access token보다 길게 설정하여 만료 기간이 짧은 Access token을 보완한다.

Refresh token은 만료 기간과 별개로 가장 최근에 발급한 토큰만이 유효해야 하기 때문에 해당 토큰을 서버의 안전한 저장소에 보관하여 검증해야 한다.

vs Session

토큰 기반의 인증이 세션 기반의 인증에 비해 갖는 장점은 크게 두 가지라고 생각한다.

  • 서버 리소스 절약
    세션 사용 시, 서버는 클라이언트로부터 전달받은 세션 ID로 해당 사용자의 데이터를 서버에서 조회한다.
    결국 필요한 데이터를 서버에 저장하고 조회해야 한다는 뜻이다.
    사용자가 많아질 수록 더 큰 저장 공간이 요구되고, 데이터가 필요할 때마다 이를 조회하기 위한 I/O가 발생한다.
    하지만 JWT는 토큰 내 Payload 파트에 데이터를 저장할 수 있기 때문에 부하를 클라이언트로 분산시킬 수 있다.

  • 확장성
    서버가 한 대라면 문제가 되지 않지만 Scale out이 필요한 경우에는 서버끼리 세션을 공유할 수 있어야 한다.
    세션을 사용한다면 이를 위한 작업이 추가적으로 필요하다.
    JWT는 데이터를 서버에서 갖고 있지 않기 때문에 서버가 여러 대여도 문제가 발생하지 않는다.

사용

현재 진행중인 개인 프로젝트에서의 회원 인증 방식으로 세션 대비 이점이 있는 토큰을 사용하게 되었다.
다만 프로젝트 성격상 초기 사용자가 많지 않을 것으로 판단하여 Refresh token 구현은 미뤄두고, Access token의 만료 기간을 길게 설정하여 사용하기로 하였다.
Access token 탈취에 대한 부분은 SSL 인증서를 설치하여 request 데이터를 암호화하는 것으로 해결하려 한다.

0개의 댓글