JWT(JSON Web Token)

흑이·2022년 3월 20일
0

스터디 주제로 JWT에 대해 공부하기로 하였다.

JWT를 먼저 공부하기 전에 먼저

인증/인가, 쿠키, 세션, 토큰에 대해 공부한 후 JWT에 대해 소개하도록 하겠다.



인증이란? (Authentication)

  • 보호된 리소스에 접근하는 것을 허용하기 이전에 등록된 유저의 신원을 입증 하는 과정
  • (식별 가능한 정보로) 서비스에 등록된 유저의 신원을 입증하는 과정
  • 예) 회원가입한 유저가 로그인한 과정이 인증


인가란? (Authorization)

  • 요청된 리소스에 접근할 수 있는 권한이 있는 인증(Authentication)된 유저 인지 입증 하는 과정
  • 인증된 사용자에 대한 자원 접근 권한 확인
  • 예) 로그인한 유저가 게시판을 수정


사전 지식

HTTP의 특징 (비연결지향, 상태없음)

  • 한번 통신하고 나면 끝나는 비연결을 지향하는 특징
  • 서버가 클라이언트의 상태를 보유하고 있지 않는 무상태성(Stateless)이라는 특징


웹에서의 인증과 인가

Request Header 이용

  • 회원가입을 완료한 유저가 로그인을 하는 과정
    • 브라우저는 요청받은 URL을 파싱한 후에 Base64 인코딩을 한 후
    • 인코딩한 데이터를 Authorization 헤더에 넣어서 서버측에 발송
    • DB 체크 및 로그인 OK 응답


로그인을 했지만, 문제점이 발생

  • 사용자가 매번 로그인을 계속 해줘야 된다는 점

예) 글을 쓸때 사용자가 로그인을 함, 글을 다 쓴다음에 수정을 하고 싶으면 인증을 한번 더 해야 함



인증을 유지시키는 기술이 필요하다!!



  • 사용자 인증 후 서버는 브라우저에 쿠키를 저장하라는 Set-Cookie 헤더를 보냄
  • Cookie는 유저의 브라우저에 저장이 됨 (ID , PASSWORD)
  • 이후 유저는 다음 요청에는 Cookie와 함께 요청을 하게 됨


사용자 입장에서 편리하지만, 해킹에 위험

  • 보안에 취약하다는 단점


보안을 향상시키는 기술이 필요하다!!

Session 이용

  • Session은 사용자의 식별자와(ID) 랜덤한 문자열로 SessionID를 만들어서 서버 DB에 정보를 저장


세션 통신 절차
1. 인증이 완료된 클라이언트가 서버에 Resource를 요청합니다.
2. 서버에서는 HTTP Request를 통해 쿠키에서 Session id를 확인을 한 후에 없으면 Set-Cookie를 통해 새로 발행한 Session-id 보냅니다.
3. 클라이언트는 HTTP Request 헤더에 Session id를 포함하여 원하는 Resource를 요청을 합니다.
4. 서버는 Session id를 통해 해당 세션을 찾아 클라이언트 상태 정보를 유지하며 적절한 응답을 합니다.



장점

쿠키보다 안전

  • 클라이언트에 저장되는 것은 유저 정보가 아니라 세션 ID
  • 세션의 만료기한을 정할 수 있어, 세션 탈취하여도 만료 이후에는 유효하지 않다. 또한 세션을 서버에서 관리하고 있기 때문에 삭제 가능


문제점

예)

  • 트래픽이 증가되어 서버를 여러대와 로드밸런서를 구축
  • 사용자는 한번 인증 후(App02), 다음 요청은 세션으로만 이용을 해서 요청을 하게 된다.
  • 이제 유저가 두 번째 인증이 필요한 요청을 하게 됨
  • 그런데 이번에 로드밸런서가 (App02)가 아닌 (App01)에 요청을 전달한다.
  • (App02)서버에만 세션 아이디 값이 있는데, (App01)은 없어 문제가 발생

서버 모두 자체적으로 세션을 관리하고 있어서 생긴 문제


세션 스토리지로 해결 가능

  • 서버들에 있는 모든 세션들을 한 곳에서 관리, 서버 뒷단에 배치(서버 -> 세션 스토리지)
  • 그러나 요청이 많아지면 부하가 클 수밖에 없음


서버에 부담이 되지 않고, 무상태성(Stateless)를 지키는 방법이 없을까?



Token 이용

- 그 중에 JSON WEB TOKEN을 사용한다.

JWT란

  • JWT는 JSON Web Token의 약자로 전자 서명 된 URL-safe (URL로 이용할 수 있는 문자만 구성된)의 JSON이다. 전자 서명은 JSON 의 변조를 체크할 수 있게 되어 있다.

  • JWT는 HMAC 알고리즘을 사용하여 비밀키 또는 RSA를 이용한 Public Key/ Private Key 쌍으로 서명할 수 있다.



JWT 구성

  • JWT는 세 파트로 나누어지며 . 을 통해 구분되며, 순서대로 Header, Payload, Signature로 구성된다.

  • 1. Header는 토큰의 타입과 해시 암호화 알고리즘으로 구성되어 있다.

    • 첫 째는 토큰의 유형 (JWT)을 나타내고

    • 두 번째는 HMAC, SHA256 또는 RSA와 같은 해시 알고리즘을 나타내는 부분이다.


  • 2. Payload는 토큰에 담을 클레임(claim) 정보를 포함하고 있다.

    • Payload에 담는 정보의 한 ‘조각’을 클레임이라고 부르고

    • 이는 name / value의 한 쌍(JSON 형식)으로 이뤄져 있다.

    • 토큰에는 여러 개의 클레임 들을 넣을 수 있다.

    • 클레임의 정보는 등록된 (registered) 클레임, 공개 (public) 클레임, 비공개 (private) 클레임으로 세 종류가 있다.


  • 3. Signature는 secret key를 포함하여 암호화되어 있다.


access token과 refresh token

access tokenrefresh token 모두 사용자가 로그인을 하고 인증됐을 경우 서버에서 Secret Key를 사용해서 발급하는 토큰이다.


access token

  • 글자 그대로 사용자가 서버에 request를 보낼 때 header에 함께 보내는 접근용 토큰

  • 만료 기간을 10~15분으로 짧게 두어 자주 발급받게 한다.

  • 이로써, 만약 access token이 다른 사람에게 도난당하더라도 금방 만료되어 안정성이 유지된다.


refresh token

  • access token이 만료됐을 때 access token을 재발급받기 위한 인증용 토큰이다.

  • 평소의 요청에는 request에 포함되지 않으면 오직 access token을 재발급받는 용도로만 사용한다.

  • 만료 기간은 자동 로그인 기능을 몇 달로 지정할 것인 가에 따라 조절하면 되고, 만료 기간이 끝나면 사용자에게 로그인을 다시 요청하면 된다.


token 생성 과정

  • 사용자가 로그인 요청을 보내고, 보내온 요청에 따라 시크릿키를 통해서 토큰을 생성한다.

  • 이때 서버는 access token 과 refresh token을 생성

  • 서버는 access token은 저장하지 않고 refresh token만 따로 저장소에 저장

  • 두 토큰을 클라이언트에 전달

  • access token이 만료가 되면, 브라우저에서는 access token과 refresh token을 함께 서버에 전달하게 됨

  • 서버는 돌아온 refresh token을 확인하여 token 갱신하게 됨



JWT 동작 방식

  1. 사용자가 로그인을 요청하고 id, pw 정보가 유효하다면
    서버에서 Secret Key를 사용해서 JWT(access token, refresh token)을 발급한다.

  2. 서버에서 JWT를 브라우저로 전달한다. 이때, 사용자의 local storage에 JWT(access token, refresh token)를 저장한다.

  3. 브라우저는 모든 request의 Authorization 헤더에 access token을 함께 전송한다.

  4. 서버는 브라우저가 보낸 access token을 식별하고 유효하다면, 원하는 응답을 제공해준다.



토큰 정리

  • 서버를 확장하는 데에 부담이 적다.

  • 토큰으로 상태관리를 하기에 따로 세션을 둘 필요가 없다. (속도가 빠름)

  • 하지만 토큰 관리를 해야한다.(토큰을 강제로 만료시킬 수 없다.) 결국 토큰도 탈취당할 수 있다 (보안에 신경을 써야 함, 유효기간을 짧게)



정리

  • 인증/인가를 위해 여러 가지 기술 쿠키, 세션, 토큰을 사용한다.

  • 각각의 장점이 존재한다고 생각하고, 역시 보안이 가장 중요하다고 생각한다.

  • 사용자 중심적으로 가용성을 더 향상시킬 것인가?

  • 아니면 보안을 위해 보안성을 높일 것인가?

  • 제공하는 서비스의 종류에 따라 중요도가 있을 것이다.



https://nesoy.github.io/articles/2017-03/Session-Cookie
https://nesoy.github.io/articles/2018-06/Load-Balancer
https://docs.microsoft.com/ko-kr/aspnet/web-api/overview/advanced/http-cookies
https://meetup.toast.com/posts/239
https://losikov.medium.com/part-6-authentication-with-jwt-json-web-token-ec78459b9c88
https://www.youtube.com/watch?v=y0xMXlOAfss
https://www.youtube.com/watch?v=TXWUNePimAc
https://www.youtube.com/watch?v=JZgD8aPkHSc

0개의 댓글