두 PWA 간의 서명된 토큰: 백엔드 없는 HMAC-SHA256
한 PWA에서 다른 PWA로 사용자 신원을 전달해야 합니다. 두 앱은 서로 다른 Firebase 프로젝트에서 실행되며, 데이터베이스도 공유하지 않고 인증 방식도 공유하지 않습니다.
백엔드 코드를 작성하지 않고도 이 문제를 해결할 수 있습니다. 브라우저의 Web Crypto API와 서명된 URL만 있으면 됩니다.
문제 상황: PanelControl이라는 내부 도구가 Orders라는 다른 사이트를 열어야 합니다. 사용자가 버튼을 클릭하면, Orders 사이트는 사용자가 누구인지 알아야 합니다. 이때 사용자가 두 번 로그인하게 해서는 안 됩니다.
세 가지 해결 방법:
- Shared Firebase: 공유 데이터베이스가 필요합니다. 여기서는 불가능합니다.
- postMessage: 동일한 도메인이거나 팝업 창이 필요합니다. 관리가 더 어렵습니다.
- HMAC 서명된 URL: 토큰이 포함된 링크를 사용합니다. 이 방법이 완벽하게 작동합니다.
작동 원리: HMAC은 비밀 키(secret key)를 사용하여 서명을 생성합니다. 수신 측은 동일한 키를 사용하여 서명을 확인합니다. 서명이 일치하면 송신자를 신뢰할 수 있습니다.
워크플로우:
- 송신 측:
- 사용자 이름과 타임스탬프가 포함된 페이로드(payload)를 생성합니다.
- HMAC-SHA256을 사용하여 페이로드에 서명합니다.
- URL에 서명과 페이로드를 추가합니다.
- 수신 측:
- URL에서 토큰을 읽습니다.
- 페이로드에서 서명을 분리합니다.
- 공유된 비밀 키를 사용하여 서명을 다시 계산합니다.
- 토큰이 만료되었는지 확인합니다 (예: 5분 경과 여부).
- 유효하다면 앱에 사용자 신원을 설정합니다.
구현 세부 사항:
Web Crypto API는 모든 현대적인 브라우저에 내장되어 있습니다. ArrayBuffer와 함께 작동하며 별도의 라이브러리가 필요하지 않습니다.
깔끔한 처리를 위해, 수신 측 스크립트는 문서의 head에서 실행됩니다. 이 스크립트는 토큰을 검증하고 시간을 확인한 후, history.replaceState를 사용하여 즉시 URL을 정리합니다. 이렇게 하면 브라우저 주소창에서 토큰이 제거되어 숨겨진 상태를 유지할 수 있습니다.
보안 주의 사항: 비밀 키는 클라이언트 코드에 존재합니다. DevTools를 사용하는 사람이라면 누구나 이를 볼 수 있습니다. 이름과 같이 민감하지 않은 데이터만 전달하는 내부 비즈니스 도구의 경우에는 이 방식이 괜찮습니다.
만약 민감한 데이터를 다루는 공개 앱을 구축한다면, 대신 서버 측 토큰을 사용하십시오. 내부 도구의 경우, 이 클라이언트 전용 방식이 빠르고 효과적입니다.
추가 인프라도, 추가 데이터베이스도 필요 없습니다. 오직 브라우저 기본 도구만 사용합니다.
Source: https://dev.to/androve2k/signed-token-between-two-pwas-hmac-sha256-with-no-backend-3jod
