본문 바로가기

Spring

토큰(Token)과 JWT

728x90

 

 

1. 토큰 인증

  • 클리아언트가 서버에 접속하면 서버에서 해당 클라이언트에게 "인증되었다는 의미"로 토큰을 부여한다.
  • 토큰은 유일하고, 토큰을 발급받은 클라이언트는 또 다시 서버에 요청을 보낼 때 요청 헤더에 토큰을 심어 보낸다.
  • 서버에서는 클라이언트로 받은 토큰을 서버에서 제공한 토큰과의 일치 여부를 체크해 인증 과정을 처리한다.
  • 앱에는 쿠키와 세션이 없기 때문에 앱과 서버가 통신 및 인증할 때 가장 많이 사용한다.

 

2. 기존 세션 기반의 인증 방식을 개선한 토큰 인증 방식

  • 기존 세션 기반의 인증은 서버가 파일이나 데이터베이스에 세션 정보를 갖고 있어야 하고 이를 조화하는 과정이 필요해 많은 오버헤드가 발생한다.
  • 토큰은 세션과 달리 서버가 아닌 "클라이언트"에 저장되기 때문에 메모리나 스토리지 등을 통해 세션을 관리했던 서버의 부담을 덜 수 있다,
    토큰 자체에 데이터가 들어았어 클라이언트에서 받아 위조 여부만 판별하면 된다!

 

3. 토큰 인증 방식

   1) 사용자가 아이디와 비밀번호로 로그인한다.

   2) 서버측에서 사용자(클라이언트)에게 유일한 토큰을 발급한다.

   3) 클라이언트는 서버 측에서 전달받은 토큰을 쿠키나 스토리지에 저장해두고 서버에 요청할 때마다 해당 토큰을

       새 http요청 헤더에 포함시켜 전달한다.

   4) 서버는 전달받은 토큰을 검증하고 응답한다.

        토큰에는 요청한 사람의 정보가 담겨있어 서버는 데이터베이스를 조회하지 않고 누가 요청하는 지 알 수 있다.

 

4. 토큰 인증의 단점

  • 토큰은 쿠키, 세션과 다르게 토큰 자체의 데이터 길이가 길어 인증 요청이 많아질수록 네트워크 부하가 심해질 수 있다.
  • payload 자체는 암호화되지 않아 유저의 중요한 정보는 담을 수 없다.
  • 토큰을 탈취당하면 대처하기가 어려운데, 사용 기간 제한을 설정하는 식으로 극복 가능하다.

 


 

5. JWT(Json Web Token) 기반 인증

  • 인증에 필요한 정보들을 암호화시킨 json토큰
  • JSON 데이터를 Base 64 URL-Safe Encode를 통해 인코딩해 직렬화한 것으로 토큰 내부에 위변조 방지를 위해 개인키를 통한 전자 서명도 들어있다.
  • 사용자가 JWT를 서버로 전송하면 서버는 서명을 검증하는 과정을 거치게 되며 검증이 완료되면 요청한 응답을 돌려준다
  • JWT토큰(Access Token)을 Http헤더에 실어 서버가 클라이언트를 식별하는 방식으로 인증이 이루어진다.

 

6. JWT 구조

aaaaaaaaa.bbbbbbbbbb.ccccccccccccc
[   header   ][   payload   ][   signature   ]

  • . 을 구분자로 나눠 Header, Payload, Signature의 문자열 조합으로 이뤄져 있다.
  • Header
    • JWT에서 사용할 타입과 해시 알고리즘 종류가 담겨져 있다.
  • Payload
    • 서버에서 첨부한 사용자 권한 정보와 데이터가 담겨있다.
    • 토큰에서 사용할 정보의 조각들인 클레임이 담겨있는 것! = 실제로 사용될 정보에 대한 내용이 담겨있는 것이다.
    • key - value 형식으로 이뤄진 한 쌍의 정보이다.
    • claim
      • Registered claims : 미리 정의된 클레임이로 발행자, 만료시간, 제목, 발행시간, Jwi Id가 담겨있다.
      • Public claims : 사용자가 정의할 수 있는 클레임으로 공개용 정보 전달을 위해 사용한다.
      • Priviate claims : 해당하는 당사자들 간에 정보를 공유하기 위해 만들어진 사용자 지정 클레임으로  
                                  외부에 공개해도 상관없고 해당 유저를 특정할 수 있는 정보를 담는다.
  • Signature
    • Header, Payload를 Base64 URL-safe Encode한 이후 헤더에 명시된 해시 함수를 적용하고 개인키로 서명한 전자 서명이 담겨있다.
  • 헤더와 페이로드는 단순 인코딩된 값으로 제 3자가 복호화 및 조작이 가능하지만 시그니처는 서버 측에서 관리하는 비밀키가 유출되지 않는 이상 복호화 할 수 없다.
  • 시그니처는 토큰의 위변조 여부를 확인하는데 사용하는 것!!

 

7. JWT 인증 과정

 

8. 토큰 인증이 신뢰성을 갖는 이유

  • 서버에서 생성한 토큰과 클라이언트로부터 받은 JWT의 헤더, 페이로드를 서버의 키 값을 이용해 시그니처를 다시 만들어  비교했을 때 일치하면 인증을 통과시킨다.
  • 토큰의 진짜 목적은 위조 방지!!!!

 

9. JWT의 장점

  • 헤더와 페이로드로 시그니처를 생성해 데이터 위변조를 막을 수 있다.
  • 인증 정보에 대한 별도의 저장소가 필요 없다.
  • JWT는 토큰에 대한 기본 정보와 전달할 정보 및 토큰이 검증되었음을 증명하는 서명 등 필요한 모든 정보를 자체적으로 지니고 있다.
  • 클라이언트 인증 정보를 저장하는 세션과 달리 서버는 stateless한 상태가 되어 서버 확장성이 우수해질 수 있다.
  • 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능하다. → 쿠키와의 차이점
  • Oauth를 이용해 로그인할 경우 JWT토큰을 발급받아 소셜 계정을 이용해 다른 웹서비스에서도 로그인할 수 있다.
  • 모바일 어플리케이션 환경에서도 작동이 잘 된다.

10. 토큰의 단점

  • self contained : 토큰 자체에 정보를 담고 있어 양날의 검이 될 수 있다.
  • 토큰 길이 : 토큰의 페이로드에 세 종류의 클레임을 저장해 정보가 많아질 수록 토큰의 길이가 늘어나 네트워크에
                       부하를 줄 수 있다.
  • 페이로드 인코딩 : 페이로드 자체는 인코딩된 것이기 때문에 중간에 페이로드를 탈취해 디코딩하면
                                 데이터를 볼 수 있어 페이로드에는 중요 정보를 담지 않도록 해야 한다.
  • store token : statelss의 특징으로 토큰은 클라이언트 측에서 관리하고 저장하기 때문에 토큰 자체를 탈취당하면                               대처하기 어렵다.

 

 

[참고 자료]

https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-JWTjson-web-token-%EB%9E%80-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC#%ED%86%A0%ED%81%B0_%EC%9D%B8%EC%A6%9D_%EC%8B%A0%EB%A2%B0%EC%84%B1%EC%9D%84_%EA%B0%80%EC%A7%80%EB%8A%94_%EC%9D%B4%EC%9C%A0

https://velog.io/@fill0006/JWTJSON-Web-Token-%EA%B5%AC%EC%A1%B0-%EB%B0%8F-%EC%9D%B4%ED%95%B4

https://puleugo.tistory.com/138#google_vignette

728x90