JWT를 어디에 저장할까?

임채욱·2021년 3월 7일
0
post-thumbnail

고민의 발단

  • WEB 슬랙 프로젝트를 진행하던중 로그인 기능을 위해 발급한 JWT를 어디에 저장하는지가 고민의 시작이었다.

  • 아래의 고민들은 대체로 사용의 편의성 및 서버 리소스 최소화를 위해 클라이언트에 저장을 하는것을 전제로 생각하였다.

JWT 관리에 대한 고민

  • local storage에 저장하면 보안상 문제가 된다. (XSS)

  • httponly, secure 옵션을 사용하여 cookie에 저장하면 local storage보다는 안전하다.

  • workspaceUserInfo의 id가 사실상 user의 id처럼 사용되기 때문에 jwt로 관리하는게 맞는 것 같다.

  • userId와 workspaceUserInfoId를 같이 jwt 토큰을 생성해야할까 따로 생성해야 할까? -> 같이 하나로 생성하자.

실제 web slack 분석

  • 실제 서비스되고 있는 web slack은 localstorage에 채널 정보와 같이 잘 변하지 않는 데이터들을 저장하여 사용하고 있다.

  • 현재 우리가 고민하는 문제는 유저 정보를 어떻게, 어디에 저장하는지가 문제가 되고 있기 때문에 참고 사항이 될 수 없었다.

  • 분명 어딘가에 로그인 유무를 확인 할 수 있는 데이터를 저장 할텐데 파악하지는 못하였다.

쿠키의 취약함을 보완 할 수 있을까?

  • singed cookie: 쿠키 암호화 옵션

  • httponly: http 통신을 통해서만 쿠키를 제어하도록 하는 옵션

  • secure: https 환경에서만 쿠키를 사용하도록 강제하는 옵션

  • 위의 옵션들을 활용하면 취약점을 보완할 수 있다.

해결

  • 현재는 jwt를 쿠키에 저장하는 방법을 사용하고 있으며 저장할 때 여러 옵션을 적용하기로 하였다.

  • 우선 signed cookie를 사용하며 https를 이용할 때 사용할 수 있는 secure 옵션을 적용하였다.

  • 또한 프론트 페이지를 제공해주는 웹서버와 API서버가 분리되어 있어 다른 도메인일 경우 쿠키를 저장하지 않도록 하는 보안 정책이 적용되었다.(CSRF 방지)

  • SameSite 속성을 변경해주면 보안 정책을 회피하여 쿠키를 저장할 수 있다. (보안적으로는 좋지 못하기 때문에 추후 다른 방법을 알아볼 예정)

최종적으로 설정한 쿠키의 옵션은 다음과 같다.

개선해야할 점

  • 현재 refresh token 없이 오로지 access token을 쿠키에 저장하여 사용하고 있기에 1시간마다 주기적으로 사용자 로그인을 다시 해줘야하는 문제점이 있다.

  • 잦은 로그인을 막기 위해 refresh token을 저장하도록하고 access token은 refresh token을 통해 주기적으로 자동 발급 되도록 개선 하면 될것 같다.

  • 좀 더 좋은 보안을 위해서는 JWT만을 보관하는 DB를 사용하고 해당 DB에 저장된 id값을 쿠키에 보관하여 refresh token으로 accss token을 발급 받을 때만 DB에 저장된 JWT를 확인하여 access token을 발급받으면 좋지 않을까 싶다.

  • access token은 탈취당하는것을 염려하여 유효기간을 주로 1시간으로 설정하기 때문에 쿠키에 저장하더라도 문제가 적을것이다.

참고사이트

profile
성장을 추구하는 개발자입니다

0개의 댓글