티스토리 뷰

공부일지(TIL)/Web

[Web] JWT

Alledy 2022. 8. 10. 22:21

토큰이란 무엇인가?

  • 웹개발에서 토큰이란 세션을 나타내는 임의 값일 뿐이다. 예를 들어 "abc123" 과 같은 문자열도 토큰이 될 수 있다.
  • 토큰의 목적은 서버가 사용자를 기억하고 분별하게 하려는 것이다.

JWT란 무엇인가?

  • JSON Web Token은 웹에서 사용하기 쉽도록 일정한 형태로 구조화한 토큰이다.
  • JWT는 JSON 데이터를 담고 있어서 JWT를 복호화하면 JSON 데이터를 얻게 된다.
  • JWT는 헤더, 페이로드, 시그니처 3부분으로 구성돼있는데 특히 이 시그니처 부분은 서버에서 암호화한 서명으로, , 시크릿 키가 없으면 복호화할 수 없다. 그러므로 내가 다른 사용자의 ID를 훔쳐서 나에게 발급된 JWT에 훔친 ID를 페이로드로 수정하여 서버에게 보낸다하더라도, 시그니처가 내 정보에 기반해서 돼있어서 validation을 통과하지 못한다.
const njwt = require('njwt') // jwt를 만드는 라이브러리
const secureRandom = require('secure-random') // 시크릿 키를 만들 라이브러리

const key = secureRandom(256, { type: 'Buffer '})

const userData = {
    id: 'someUser'
}

const jwt = njwt.create(userData, key) // 유저 정보와 시크릿 키를 담아서 jwt를 만듦
const token = jwt.compact() // 네트워크를 통해 전송할 수 있는 간소화된 폼으로 변형

njwt.verify(token, key) // verify with secretKey

왜 JWT를 사용하는가?

  • 전통적으로는 세션 / 쿠키 방식이 세션을 유지하고 판별하는 방식으로 가장 많이 사용되고 있었다. 클라이언트는 세션 ID를 쿠키에 보관하고 인증이 필요할 때마다 해당 쿠키를 서버에 전송하고, 서버는 세션 ID를 받아서 세션 저장소에 보관하고 있는 세션 정보를 열람하고 인증하는 방식이었다.
  • 이 방식의 단점은 서버 쪽에서 세션 정보를 저장하는 DB와 세션 캐시 등을 따로 만들고 관리해야 한다는 부분인데, JWT는 이 방식과 달리 유저 정보를 직접 토큰 안에 담기 때문에 토큰이 왔을 때 서버는 이를 시크릿 키로 인증하기만 하면 된다.
  • 즉 서버 세션을 만들고 관리함으로써 생기는 레이턴시 패널티가 없고, 인증 서버는 상태를 유지할 필요가 없으므로 토큰은 stateless한 인증 방식이다.

JWT를 도둑 맞는다면?

  • JWT를 탈취당하면 계정에 대한 full access가 가능하기 때문에, 거의 id랑 패스워드를 훔친 것만큼이나 크리티컬하다.
  • 그나마 id 패스워드를 뺏긴 것보다 나은 점은 JWT에 expire date을 설정할 수 있다는 점이다.
  • JWT는 패스워드만큼이나 중요하게 보관돼야 하므로 서드 파티 스크립트가 접근가능한 로컬 스토리지 같은 곳에는 저장하면 안되고(xss attack) httpOnly 쿠키처럼 자바스크립트에서 접근할 수 없는 곳에 저장해야 한다. (* httpOnly 쿠키: 서버에 http 전송할 때만 사용할 수 있는 쿠키로서 브라우저 자바스크립트로 읽거나 쓰는 것이 불가하다.)
  • 만약 JWT를 탈취당한 경우에는 토큰을 무효화시켜서 해커가 새로운 토큰을 얻을 때까지 일시적으로 시간을 벌거나, 유저에게 비밀번호를 바꾸라고 강제해서 해커가 계정 정보를 바꾸는 것을 방지하는 방법 등이 있다.

엑세스 토큰과 리프레시 토큰

  • JWT의 expire date은 trade off가 있다. 짧을 수록 보안에 유리하지만 사용자는 불편을 겪는다.
  • 그래서 엑세스 토큰과 리프레시 토큰이라는 개념이 등장한다.
  • 로그인했을 때 서버는 확인 후 엑세스 토큰과 리프레시 토큰을 발급한다. (일반적으로 그렇다는 소리이다. 실제 구현에 따라서 조금씩 다를 수 있다.)
  • 클라이언트는 리프레시 토큰을 안전한 곳에 저장하고, 엑세스 토큰을 서버에게 요청마다 전송한다.
  • 그러던 중 유효기간이 만료되면 서버는 유효기간이 만료된 토큰이라는 것을 클라이언트에 알려주고, 클라이언트는 갱신을 위해 리프레시 토큰과 엑세스 토큰을 같이 보낸다.
  • 서버는 저장하고 있던 리프레시 토큰과 사용자가 보낸 리프레시 토큰을 비교하여 동일한지 확인하고, 만료되지 않았다면 새로운 액세스 토큰을 발급해준다.
  • 리프레시 토큰이 만료된 경우에는 재로그인이 필요하다.

Ref

https://developer.okta.com/blog/2018/06/20/what-happens-if-your-jwt-is-stolen

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함