본문 바로가기
🗂️CS & Other/Jwt

[Jwt] 토큰 기반 인증(JWT)이란?

by inbeom 2023. 9. 8.
728x90

토큰 기반 인증(JWT) 사용 이유

 

[ 세션 기반 인증 시스템의 문제점 ]

1. 세션

사용자가 인증을 할 때, 서버는 이러한 정보를 저장해야 하고 이를 세션(Session)이라고 부른다. 대부분의 경우에는 메모리에 저장하는데, 로그인 중인 사용자가 늘어날 경우에는 서버의 RAM에 부하가 걸리게 된다. 이를 피하기 위해 데이터베이스에 저장을 하기도 하는데, 이러한 방식 역시 데이터베이스에 무리를 줄 수 있다.

 

2. 확장성

사용자가 늘어나게 되면 더 많은 트래픽을 처리하기 위해 여러 프로세스를 돌리거나 컴퓨터를 추가하는 등 서버를 확장해야 한다. 세션을 사용한다면 세션을 분산시키는 시스템을 설계해야 하지만 이러한 과정은 매우 어렵고 복잡한다.

 

3. CORS(Cross-Origin Resource Sharing)

웹 어플리케이션에서 세션을 관리할 때 자주 사용되는 쿠키는 단일 도메인 및 서브 도메인에서만 작동하도록 설계되어 있다. 따라서 쿠키를 여러 도메인에서 관리하는 것은 번거롭다.

Server(session) 기반 인증 방식은 소규모 시스템에서는 아직 많이 사용되고 있지만, 웹/앱 애플리케이션이 발달하게 되면서 위와 같은 문제들로 token기반 인증의 사용이 많아지고 있다.

 

[ 토큰 기반 인증 시스템의 이점 ]

 

1. 무상태성(Stateless) & 확장성(Scalability)

토큰은 클라이언트 측에 저장되기 때문에 서버는 완전히 Stateless하며, 클라이언트와 서버의 연결고리가 없기 때문에 확장하기에 매우 적합하다.

만약 사용자 정보가 서버 측 세션에 저장된 경우에 서버를 확장하여 분산처리 한다면, 해당 사용자는 처음 로그인 했었던 서버에만 요청을 받도록 설정을 해주어야 한다. 하지만 토큰을 사용한다면 어떠한 서버로 요청이 와도 상관이 없다.

 

2. 보안성

클라이언트가 서버로 요청을 보낼 때 더 이상 쿠키를 전달하지 않으므로, 쿠키 사용에 의한 취약점이 사라지게 된다. 하지만 토큰 환경의 취약점이 존재할 수 있으므로 이에 대비해야 한다.

 

3. 확장성(Extensibility)

시스템의 확장성을 의미하는 Scalability와 달리 Extensibility는 로그인 정보가 사용되는 분야의 확장성을 의미한다.

토큰 기반의 인증 시스템에서는 토큰에 선택적인 권한만 부여하여 발급할 수 있으며 OAuth의 경우 Facebook, Google 등과 같은 소셜 계정을 이용하여 다른 웹 서비스에서도 로그인을 할 수 있다.

 

4. 여러 플랫폼 및 도메인

서버 기반 인증 시스템의 문제점 중 하나인 CORS를 해결할 수 있는데, 애플리케이션과 서비스의 규모가 커지면 여러 디바이스를 호환시키고 더 많은 종류의 서비스를 제공하게 된다.

토큰을 사용한다면 어떤 디바이스, 어떤 도메인에서도 토큰의 유효성 검사를 진행한 후에 요청을 처리할 수 있다. 이런 구조를 통해 assests 파일(Image, html, css, js 등)은 모두 CDN에서 제공하고, 서버 측에서는 API만 다루도록 설게할 수 있다.

최근에는 Json 포맷을 이용하는 JWT(Json Web Token)을 주로 사용한다.


💡 *JWT(Json Web Token)란 Json 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token이다.

  • JWT는 토큰 자체를 정보로 사용하는 Self-Contained 방식으로 정보를 안전하게 전달한다.
  • 주로 회원 인증이나 정보 전달에 사용되는 JWT는 아래의 로직을 따라서 처리된다.

 

JWT 구조

JWT는 Header, Payload, Signature의 3 부분으로 이루어지며, Json 형태인 각 부분은 Base64Url로 인코딩 되어 표현된다.

 

1. Header(헤더)

토큰의 헤더는 typ과 alg 두 가지 정보로 구성된다. alg는 헤더(Header)를 암호화 하는 것이 아니고, Signature를 해싱하기 위한 알고리즘을 지정하는 것이다.

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

 

2. PayLoad(페이로드)

토큰의 페이로드에는 토큰에서 사용할 정보의 조각들인 **클레임(Claim)**이 담겨 있다.

클레임은 총 3가지로 나누어지며, Json(Key/Value) 형태로 다수의 정보를 넣을 수 있다.

등록된 클레임(Registered Claim) 공개 클레임(Public Claim) 비공개 클레임(Private Claim)

3. Signature(서명)

서명(Signature)은 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드이다. 서명(Signature)은 위에서 만든 헤더(Header)와 페이로드(Payload)의 값을 각각 BASE64Url로 인코딩하고, 인코딩한 값을 비밀 키를 이용해 헤더(Header)에서 정의한 알고리즘으로 해싱을 하고, 이 값을 다시 BASE64Url로 인코딩하여 생성한다.

 

JWT 단점 및 고려사항

  • Self-contained: 토큰 자체에 정보를 담고 있으므로 양날의 검이 될 수 있다.
  • 토큰 길이: 토큰의 페이로드(Payload)에 3종류의 클레임을 저장하기 때문에, 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있다.
  • Payload 인코딩: 페이로드(Payload) 자체는 암호화 된 것이 아니라, BASE64Url로 인코딩 된 것이다. 중간에 Payload를 탈취하여 디코딩하면 데이터를 볼 수 있으므로, JWE로 암호화하거나 Payload에 중요 데이터를 넣지 않아야 한다.
  • Stateless: JWT는 상태를 저장하지 않기 때문에 한번 만들어지면 제어가 불가능하다. 즉, 토큰을 임의로 삭제하는 것이 불가능하므로 토큰 만료 시간을 꼭 넣어주어야 한다.
  • Store Token: 토큰은 클라이언트 측에서 관리해야 하기 때문에, 토큰을 저장해야 한다.

 

Ex> 토큰 생성

public static String generateToken(String userName, String key, long expiredTimeMs){
        Claims claims = Jwts.claims();
        claims.put("userName", userName);

        return Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + expiredTimeMs))
                .signWith(getKey(key), SignatureAlgorithm.HS256)
                .compact();
    }

 

 

 

JWT 보안 이슈

https://velog.io/@thelm3716/JWTvul

 

JWT (JSON Web Token) 취약점 알아보기

JWT(JSON Web Token)의 취약점을 알아봅니다.

velog.io

 

728x90