JWT 인증 ‐ 쿠키 vs 헤더 (SSR 기준) - nhnacademy-be10-WannaB/wannab-wiki GitHub Wiki

왜 이 주제를 정리했는가!?

  • 저는 기존에 프로젝트를 진행할때 프론트엔드 팀 + 백엔드 팀 으로 프로젝트를 진행한 적이 많습니다.
    • 프론트엔드 팀은 보통 기술 스택으로 Vue.js 또는 React.js를 사용했고, 해당 스택들은 모두 CSR입니다.
      • 이때, 항상 기계적으로 Authorization 헤더로 토큰을 전달해 주었습니다.
    • 그러나 이번에는 Thymeleaf를 이용한 SSR를 이용하기 때문에 JWT를 어떻게 관리해야하는지 궁금하여 유저 서비스 팀과 논의하다가 공부해보았습니다.
  • 좋은 내용이라 생각해 정리 후 공유합니다!

1. 보안적 측면에서는?

쿠키 기반 토큰 전달

  • HttpOnly 속성을 통해서 JS로 조작을 아예 못하게 막을 수 있음
    • 이는 XSS 보안 위협에 대응이 가능함을 의미
  • CSRF 토큰 또는 SameSite 쿠키 옵션 등을 통해 CSRF 공격도 대비가 가능함 ⇒ 즉, 쿠키 사용의 주요 보안 약점은 거의 완화됨

Authorization 헤더 기반 토큰 전달

  • CSR에서는 헤더 기반으로 토큰을 전달하면 Vue, React 코드에서 메모리를 활용해 토큰을 관리한다고 이해하고 있습니다.
  • 하지만 우리 서비스는 SSR 방식 + Thymeleaf 이기 때문에, JS를 활용해 토큰을 관리하기 까다롭습니다..
    • HttpOnly 속성을 걸면 프론트 서비스에서 JS등으로 토큰을 어딘가에 저장할 수 없게 되고
    • 그렇다고, 속성을 걸지 않으면 프론트 서비스에서 토큰을 관리하기 어렵습니다..

결론

  • 보안적 측면에서 봤을 때, SSR이 쿠키 기반 토큰 전달 방식이 조금 더 안전하고 편리하다.

2. 구현복잡도 측면에서 보면?

쿠키 기반 구현

  • 유저 서비스에서 토큰을 생성 후 쿠키로 전달하면, 브라우저는 이후 별도의 추가적인 로직없이 발급받은 쿠키를 자동으로 저장/전송을 해줌
    • 즉, 프론트단에서 추가적인 로직을 구현할 필요가 없음

헤더 기반 구현

  • SSR에서는 모든 요청이 전체 페이지 리로딩하는 방식으로 이루어짐
    • 이 경우, 브라우저는 개발자가 지정한 커스텀 헤더를 붙여주지 않음
    • 즉, JS로 fetch 또는 axios 등을 이용해 JWT를 헤더에 담아 API 호출을 해야하는데, 이 경우 SSR임에도 SPA같은 구현이 필요해지게 됨..
  • 그리고 JWT를 클라이언트에게 전달하려면 브라우저 내에 토큰을 저장할 방법도 필요함
    • Localstorage
  • 즉, 구현이 복잡하고 제약도 큼

결론

  • 쿠키 기반 방식이 구현이 간단함

두 내용을 기반으로 결론

  • SSR 환경에서는 쿠키 기반 JWT 관리 방식이 더 적합하다
  • 잘못된 내용 지적, 태클, 반박 언제나 환영입니다
  • 질문이 있다면, @gnsals0904에게 해주세요

레퍼런스