프로젝트

일반

사용자정보

Actions

이슈 #411

진행중
JL JL

Supabase GoTrue 인증 전환 — wallet-based auth 제거 및 GoTrue JWT 통합

이슈 #411: Supabase GoTrue 인증 전환 — wallet-based auth 제거 및 GoTrue JWT 통합

James Lee이(가) 약 5시간 전에 추가함.

상태:
해결
우선순위:
보통
담당자:
목표버전:
시작일:
2026/04/24
완료일:
진척도:

0%

추정시간:

설명

개요

기존 wallet address 기반 secp256k1 challenge/verify 인증을 Supabase GoTrue(자체 호스팅)로 전환한다.

배경

  • 기존 구조에서는 wallet private key = 사용자 identity였음
  • 모바일 다중 디바이스 환경에서 private key 동기화 불가 → 근본적 문제
  • wallet address는 보상 수신 주소(reward destination)로만 사용되어야 하며, 특정 사용자에 종속되지 않아야 함

변경 범위

인증 레이어

  • GoTrue(supabase/gotrue) 서비스를 docker-compose에 추가 (port 9011)
  • JWT 검증을 표준 HMAC-SHA256으로 교체 (jsonwebtoken crate, GoTrue 호환)
  • AuthContext: user_id (GoTrue UUID) + email + token_type ("user" | "node")
  • Node 토큰은 별도 유지 (typ: "node", sub = node_id)

프로토 / AuthService

  • AuthService RPC를 GenerateKeypair 하나로 축소 (Challenge/Verify/Register 제거)
  • secp256k1 챌린지는 노드 등록(NodeService)에만 남김

DB 스키마 (migrations/0006_supabase_auth_schema.sql)

  • accounts 테이블 재설계: user_id UUID PK (GoTrue sub), email, display_name, profile_icon
  • wallets 테이블 신설: user_id → wallet_address (1:N, 보상 지갑 목록)
  • nodes.owner_user_id UUID 컬럼 추가 (노드 소유 사용자 추적)
  • 기존 wallet address 기반 계정 데이터 DROP

핸들러 변경

  • register_node: GoTrue JWT 필수, owner_user_id = JWT sub
  • heartbeat / delete_node: owner_user_id 기준 소유권 검증
  • get_user: wallet → wallets 테이블 join으로 조회
  • Admin HTTP 콘솔: challenge/verify 엔드포인트 제거, GoTrue JWT paste UI 추가

tools/client.py

  • Python gRPC 테스트 클라이언트에서 Auth Challenge/Verify 메뉴 제거

GoTrue 설정 (개발)

GOTRUE_JWT_SECRET: JWT_SECRET 환경변수와 동일값으로 설정
GOTRUE_MAILER_AUTOCONFIRM: true
GOTRUE_SITE_URL: http://localhost:3000

Sign-up: POST :9011/signup {"email":"…","password":"…"}
Login: POST :9011/token?grant_type=password {"email":"…","password":"…"}


연결된 일감 6 (6 건 진행 중 — 모두 미완료)

다음 일감과 관련됨: 이슈 #420: Redeem Code 시스템 — 사용권 발급/리딤/관리 (QR 코드 기반)해결James Lee2026/04/282026/04/29

Actions
다음 일감과 관련됨: 이슈 #421: AGX 잔액을 Wallet 종속 → Account(GoTrue user_id) 종속으로 전환해결James Lee2026/04/27

Actions
다음 일감과 관련됨: 보고 #422: Examples 정리 — GoTrue 전환 후 broken 상태로 남은 auth_roundtrip / user_get해결James Lee2026/04/27

Actions
다음 일감과 관련됨: 이슈 #424: Dev Console 에 GoTrue Sign Up / Log In 통합 — 테스트 환경 간소화해결James Lee2026/04/27

Actions
다음 일감과 관련됨: 이슈 #419: Supabase Auth 적용, 앱 로그인 테스트신규Ryan Lee2026/04/272026/05/01

Actions
다음 일감과 관련됨: 이슈 #434: [Go backport] Supabase GoTrue 인증 전환 — Phase 1: 인프라 + 인증 코어해결Henry Park2026/05/11

Actions

JL James Lee이(가) 6달 전에 변경 Actions #1

구현 완료 (commit:server|8f52241)

변경 파일 요약

인증 레이어 (src/domain/auth/, src/server/auth_middleware.rs)

  • jsonwebtoken crate 기반 표준 HMAC-SHA256 JWT 검증으로 교체
  • AuthContext: user_id (GoTrue UUID or node_id), email, token_type ("user" | "node")
  • GoTrue 발행 토큰: typ claim 없음 → token_type = "user"
  • Node 토큰: typ: "node", sub = node_id 유지
  • Public path set에서 Challenge/Verify 제거; RegisterNode는 보호 RPC로 전환

프로토 (proto/alphea/v1/auth.proto)

  • AuthService를 GenerateKeypair 단일 RPC로 축소

DB 마이그레이션 (migrations/0006_supabase_auth_schema.sql)

  • accounts 재설계: user_id UUID PK, email, display_name, profile_icon
  • wallets 신설: user_id → wallet_address (1:N)
  • nodes.owner_user_id UUID 추가
  • 기존 wallet identity 데이터 DROP

핸들러

  • handler/node.rs: register_node — GoTrue JWT 필수, owner_user_id 저장; heartbeat/delete_node — owner_user_id 기준 소유권 검증
  • handler/user.rs: get_user — wallets 테이블 join으로 조회
  • handler/auth.rs: GenerateKeypair만 남김

Admin 콘솔 (src/admin/mod.rs)

  • /api/auth/challenge, /api/auth/verify 라우트 제거
  • 노드 등록에 JWT 필수 적용
  • owner_wallet_address → owner_user_id 소유권 검증으로 전환
  • Wallet 엔드포인트: wallet 소유권 assertion 제거 (wallet은 보상 주소일 뿐)
  • UI: challenge/verify 카드 제거 → GoTrue JWT paste 카드 추가

인프라 (docker-compose.yml)

  • gotrue 서비스 추가 (port 9011, supabase/gotrue:v2.158.1)

의존성 (Cargo.toml)

  • sqlx uuid feature 추가
  • jsonwebtoken = "9" 추가

남은 작업

  • GoTrue 연동 통합 테스트 (실 서버 환경)
  • 모바일 앱 auth flow 업데이트 (GoTrue SDK 적용)

JL James Lee이(가) 6달 전에 변경 Actions #2

  • 상태을(를) 신규에서 해결(으)로 변경되었습니다.

Dev Console & 테스트 클라이언트 GoTrue 인증 적용 (commit:server|442ebd1)

tools/client.py

Auth 메뉴 교체

  • 기존: Challenge → Sign → Verify, EmailRegister, Login (wallet 기반)
  • 변경: GoTrue Sign up / Log in (HTTP → GoTrue REST API) + JWT paste

GoTrue 통신은 표준 urllib 사용 (추가 의존성 없음):

POST <gotrue_url>/signup            {"email":"…","password":"…"}
POST <gotrue_url>/token?grant_type=password   {"email":"…","password":"…"}

로그인 성공 시 access_token, user.id, user.email 상태에 저장.

Node 등록 변경

  • GoTrue JWT 없으면 등록 차단 (안내 메시지 출력)
  • NodeChallengeRequest에서 owner_wallet_address 제거 (node_id만 전송)
  • RegisterNode 호출 시 user JWT metadata 포함

--gotrue CLI 플래그 추가

  • 기본값: localhost → http://localhost:9011, 원격 TLS → https://<host>:9011
  • 기존 state에 _gotrue_url 로 저장 (재시작 시 유지)

상태 표시 개선

  • show_state: wallet → email, user_id, node_token 표시로 개편
  • 메인 메뉴 상단: wallet=… → email 표시

src/admin/mod.rs (Dev Console)

  • JWT bar placeholder 문구 업데이트
  • JWT bar: click-to-copy 동작 추가
  • clearAll 시 gotrue-jwt input도 함께 초기화

JL James Lee이(가) 6달 전에 변경 Actions #3

CLAUDE.md 컨벤션 보완

commit:server|dd699eb

Redmine 댓글 작성 규칙 추가: commit:server|<hash> 링크는 댓글 제목(heading) 이 아닌 본문에 포함해야 함. CLAUDE.md 및 프로젝트 메모리에 명시.

JL James Lee이(가) 6달 전에 변경 Actions #4

  • 다음 일감과 관련됨:에 이슈 #420: Redeem Code 시스템 — 사용권 발급/리딤/관리 (QR 코드 기반)이(가) 추가되었습니다.

JL James Lee이(가) 6달 전에 변경 Actions #5

  • 다음 일감과 관련됨:에 이슈 #421: AGX 잔액을 Wallet 종속 → Account(GoTrue user_id) 종속으로 전환이(가) 추가되었습니다.

JL James Lee이(가) 6달 전에 변경 Actions #6

  • 다음 일감과 관련됨:에 보고 #422: Examples 정리 — GoTrue 전환 후 broken 상태로 남은 auth_roundtrip / user_get이(가) 추가되었습니다.

JL James Lee이(가) 6달 전에 변경 Actions #7

  • 다음 일감과 관련됨:에 이슈 #424: Dev Console 에 GoTrue Sign Up / Log In 통합 — 테스트 환경 간소화이(가) 추가되었습니다.

JL James Lee이(가) 6달 전에 변경 Actions #8

후속 — 가입 / 로그인 audit 로그 + 클라이언트 IP 추적

commit:server|c519434

GoTrue proxy 의 signup/login endpoint 에 audit 로그 추가. 성공/실패 모두 기록 + 요청 IP 정밀 추적.

추가된 로그

Action 결과 Fields
signup success email, ip, user_id (GoTrue id)
signup failure email, ip, error (GoTrue 에러 메시지)
login success email, ip, user_id
login failure email, ip, error
  • 모두 WARN 레벨
  • Target: audit::auth (Dev Console 의 target filter 에 audit 또는 auth 입력 시 필터링)

Client IP 추출 (client_ip 헬퍼)

우선순위:

  1. CF-Connecting-IP (Cloudflare)
  2. X-Real-IP (nginx)
  3. X-Forwarded-For 의 첫 항목 (가장 원래의 client)
  4. axum ConnectInfo 의 connection peer

→ reverse proxy 환경에서도 실제 client 의 IP 를 정확히 캡처. proxy 가 위 헤더들을 덮어쓰는 게 보안상 중요 (클라이언트가 임의로 헤더 보내면 IP spoofing 가능).

Axum Routing 변경

admin::run 을 into_make_service_with_connect_info::<SocketAddr>() 로 마운트하여 핸들러가 ConnectInfo<SocketAddr> 를 추출 가능하게 함.

보안 고려

  • 비밀번호는 절대 로그에 남지 않음 (body 자체를 GoTrue 로 forward 만 하고 로깅엔 email/ip 만)
  • 실패 case 도 기록 — brute-force 시도 탐지 가능
  • 동일 IP 에서 다수 실패는 audit log 에서 grep 만으로 발견

Dev Console 에서 보는 법

  1. Logs 탭
  2. Level: WARN 또는 ALL
  3. Target filter: audit (모든 audit) 또는 audit::auth (인증만)

검증

  • cargo build 성공
  • cargo test --lib 54 passed
  • cargo clippy --all-targets clean

운영 적용

git pull
docker compose up -d --build app

이후 Dev Console Auth 탭에서 Sign Up / Log In → Logs 탭에서 audit 로그 확인 가능.

JL James Lee이(가) 6달 전에 변경 Actions #9

  • 다음 일감과 관련됨:에 이슈 #419: Supabase Auth 적용, 앱 로그인 테스트이(가) 추가되었습니다.

JL James Lee이(가) 6달 전에 변경 Actions #10

  • 다음 일감과 관련됨:에 이슈 #434: [Go backport] Supabase GoTrue 인증 전환 — Phase 1: 인프라 + 인증 코어이(가) 추가되었습니다.

JL James Lee이(가) 6달 전에 변경 Actions #11

Go 원본 프로젝트(alphea-rpc-next) 로의 백포트 — Phase 1 반영

후속 이슈 #434 에서 발생. 본 이슈의 핵심 설계(GoTrue 인증 / accounts.user_id / nodes.owner_user_id / AuthService 축소) 를 그대로 Go 측으로 옮겨왔다.

commit:server|03c6c64

Go 측에 적용된 있어서의 차이

  • JWT 라이브러리: Rust jsonwebtoken → Go github.com/golang-jwt/jwt/v4. 동일한 HS256 표준 구현
  • Tower Layer → ConnectRPC connect.UnaryInterceptorFunc. AuthContext 는 동일 구조체로 설계 (UserID / NodeID / Email / TokenType / Wallet)
  • DB 마이그레이션: Rust 의 0006 그대로 옷아오지 않고, 기존 Go 프로젝트의 멀티-서비스 스키마(accounts/wallets/friends/rewards_log/referral_claims)를 고려해 v12 단일 마이그레이션으로 적용. 구조적으로는 additive ALTER 와 식별권한 TRUNCATE 조합
  • Rust 춝 8개 관련 이슈(#411 / #421 / #422 / #424 / #419 / #420) 중 본 이슈 범위만 반영. AGX 회계 재설계(원본 #421)는 Go 백포트의 Phase 2 이슈에서 처리
  • Admin Dev Console 의 GoTrue UI(원본 #424)는 Phase 3 이슈에서 처리. 본 커밋은 docker-compose.yml + Postgres init 스크립트 설정만 동반

제외된 RPC

AuthService 의 Challenge / Verify / Login / SetPassword / EmailRegister / EmailRecover 는 proto 에서 완전 제거. 노드 온보딩용 challenge-response 는 NodeService.NodeChallenge + RegisterNode 경로로 유지 (단, RegisterNode 는 이제 user JWT 명시적으로 요구).

HP Henry Park이(가) 6달 전에 변경 Actions #12

후속 docs 정리

commit:server|a7b3c4f 에서 GoTrue 도입 이후 documentation 을 정렬:

  • docs/01-auth.md 전면 재작성 — GoTrue REST + NodeService 흐름 명시
  • docs/00-overview.md / docs/07-api-reference.md — AuthService 가 GenerateKeypair 만 남은 상태 반영 (60 RPCs)
  • docs/06-mobile-sdk.md — 옷 wallet-challenge 흐름이 stale 임 경고
  • CLAUDE.md — 서비스 카운트 동기화 (auth 1, total 60)

#440 의 작업 일부.

Actions

내보내기 PDF Atom