계정 추가: OAuth/Refresh Token 이중 채널과 모범 사례
Antigravity Tools에서 "계정 추가"는 Google 계정의 refresh_token을 로컬 계정 풀에 작성하여 이후 역방향 프록시 요청에서 순환하여 사용할 수 있게 하는 것입니다. OAuth 일회성 권한 부여를 사용하거나 refresh_token을 직접 붙여넣어 수동으로 추가할 수 있습니다.
학습 완료 후 가능한 작업
- OAuth 또는 Refresh Token을 사용하여 Google 계정을 Antigravity Tools 계정 풀에 추가
- 권한 부여 링크 복사/수동 열기, 콜백 성공 후 자동으로 추가 완료
refresh_token을 얻을 수 없거나localhost에 연결할 수 없는 문제 발생 시 해결 방법 파악
현재 겪고 있는 문제
- "OAuth 권한 부여"를 클릭했지만 계속 로딩 중이거나 브라우저에서
localhost refused to connect오류 발생 - 권한 부여 성공 후 "Refresh Token을 가져오지 못함" 메시지 표시
refresh_token만 가지고 있어서 일괄로 가져오는 방법을 모름
이 기능을 언제 사용해야 할까
- 계정을 가장 안정적인 방법으로 추가하고 싶을 때 (OAuth 우선)
- 마이그레이션 가능/백업 가능을 더 중요하게 생각할 때 (Refresh Token이 "계정 풀 자산"으로 더 적합)
- 많은 계정을 추가하고
refresh_token을 일괄로 가져오고 싶을 때 (텍스트/JSON에서 추출 지원)
🎒 시작 전 준비
- Antigravity Tools 데스크톱 버전을 설치하고 실행 가능한 상태
- 진입 경로 파악: 왼쪽 네비게이션에서
Accounts페이지로 진입 (라우트는source/lbjlaq/Antigravity-Manager/src/App.tsx참조)
이 수업에서 자주 등장하는 두 가지 핵심 키워드
OAuth: "브라우저로 이동하여 로그인하고 권한 부여"하는 프로세스. Antigravity Tools는 로컬에 임시 콜백 주소를 생성 (http://localhost/127.0.0.1/[::1]:<port>/oauth-callback, 시스템 IPv4/IPv6 수신 상태에 따라 자동 선택)하고, 브라우저가 code를 가져오면 토큰으로 교환 (구현은 source/lbjlaq/Antigravity-Manager/src-tauri/src/modules/oauth_server.rs 참조)
refresh_token: "access_token을 장기적으로 갱신할 수 있는 자격 증명". 이 프로젝트에서 계정을 추가할 때 먼저 access_token으로 교환한 다음 Google에서 실제 이메일을 가져오고, 프론트엔드에서 입력한 email은 무시함 (구현은 source/lbjlaq/Antigravity-Manager/src-tauri/src/commands/mod.rs 참조)
핵심 개념
Antigravity Tools의 "계정 추가"는 결국 사용 가능한 refresh_token을 확보하고 계정 정보를 로컬 계정 풀에 작성하는 것을 목표로 합니다.
- OAuth 채널: 애플리케이션이 권한 부여 링크를 생성하고 로컬 콜백을 수신 대기; 권한 부여 완료 후 자동으로 토큰 교환 및 계정 저장 (
prepare_oauth_url,start_oauth_login,complete_oauth_login참조) - Refresh Token 채널:
refresh_token을 직접 붙여넣으면, 애플리케이션이 이를 사용하여 access_token을 갱신하고 Google에서 실제 이메일을 가져와서 저장 (add_account참조)
함께 실습
1단계: "계정 추가" 대화상자 열기
이유 모든 추가 진입점은 Accounts 페이지에서 통합 관리됩니다.
작업: Accounts 페이지로 이동하여 오른쪽의 Add Account 버튼 클릭 (컴포넌트: AddAccountDialog).
예상 화면: 3개의 탭을 포함하는 대화상자가 표시됨: OAuth / Refresh Token / Import (source/lbjlaq/Antigravity-Manager/src/components/accounts/AddAccountDialog.tsx 참조).
2단계: OAuth 일회성 권한 부여 우선 사용 (권장)
이유 제품의 기본 권장 경로: 애플리케이션이 권한 부여 링크를 자동으로 생성하고 기본 브라우저를 열며, 콜백이 돌아오면 자동으로 저장 완료.
OAuth탭으로 전환.- 먼저 권한 부여 링크 복사: 대화상자가 열리면 자동으로
prepare_oauth_url을 호출하여 URL 미리 생성 (프론트엔드 호출은AddAccountDialog.tsx:111-125참조; 백엔드 생성 및 수신은oauth_server.rs참조). - Start OAuth 클릭 (프론트엔드
startOAuthLogin()/ 백엔드start_oauth_login해당), 애플리케이션이 기본 브라우저를 열고 콜백 대기 시작.
예상 화면:
- 대화상자에 복사 가능한 권한 부여 링크 표시됨 (이벤트 이름:
oauth-url-generated) - 브라우저에서 Google 권한 부여 페이지 열림; 권한 부여 후 로컬 주소로 리디렉션되고 "Authorization Successful!" 표시됨 (
oauth_success_html())
3단계: OAuth가 자동으로 완료되지 않을 때, "OAuth 완료"로 수동 마무리
이유 OAuth 프로세스는 두 단계로 나뉨: 브라우저 권한 부여로 code 획득, 그 다음 애플리케이션이 code로 토큰 교환. "Start OAuth"를 클릭하지 않더라도 권한 부여 링크를 수동으로 열고 콜백을 완료하면 대화상자가 자동으로 마무리 시도; 마무리 실패 시 수동으로 한 번 클릭.
- "링크를 복사하여 자신의 브라우저에서 열기"(기본 브라우저 아님)를 한 경우, 권한 부여 콜백이 돌아오면 애플리케이션이
oauth-callback-received이벤트를 수신하고 자동으로completeOAuthLogin()호출 (source/lbjlaq/Antigravity-Manager/src/components/accounts/AddAccountDialog.tsx:67-109참조). - 자동 완료가 보이지 않으면, 대화상자에서 Finish OAuth 클릭 (백엔드
complete_oauth_login해당).
예상 화면: 대화상자에서 성공 메시지 표시되고 자동으로 닫힘; Accounts 목록에 새 계정 표시됨.
팁: 콜백 연결 실패 시 링크 복사 우선
백엔드는 가능한 한 IPv6 ::1과 IPv4 127.0.0.1을 동시에 수신 대기하고, 수신 상태에 따라 localhost/127.0.0.1/[::1]을 콜백 주소로 선택. 주로 "브라우저가 localhost를 IPv6로 해석"으로 인한 연결 실패를 방지하기 위함 (source/lbjlaq/Antigravity-Manager/src-tauri/src/modules/oauth_server.rs:53-113 참조).
4단계: Refresh Token으로 수동 추가 (일괄 지원)
이유refresh_token을 얻을 수 없거나(또는 "마이그레이션 가능 자산"을 더 선호할 때), Refresh Token으로 직접 추가하는 것이 더 제어 가능.
Refresh Token탭으로 전환.refresh_token을 텍스트 상자에 붙여넣기.
지원하는 입력 형식 (프론트엔드가 분석하여 일괄 추가):
| 입력 유형 | 예시 | 분석 로직 |
|---|---|---|
| 순수 토큰 텍스트 | 1//abc... | 정규식 추출: /1\/\/[a-zA-Z0-9_\-]+/g (AddAccountDialog.tsx:213-220 참조) |
| 큰 텍스트 내에 포함 | 로그/내보내기 텍스트에 여러 개의 1//... 포함 | 정규식 일괄 추출 및 중복 제거 (AddAccountDialog.tsx:213-224 참조) |
| JSON 배열 | [{"refresh_token":"1//..."}] | 배열 분석 후 item.refresh_token 추출 (AddAccountDialog.tsx:198-207 참조) |
Confirm 클릭 후, 대화상자가 토큰 수량만큼 순차적으로 onAdd("", token) 호출 (AddAccountDialog.tsx:231-248 참조), 최종적으로 백엔드 add_account에 전달.
예상 화면:
- 대화상자에 일괄 진도 표시 (예:
1/5) - 성공 후
Accounts목록에 새 계정 표시됨
5단계: "계정 풀 사용 가능" 확인
이유 추가 성공이 "즉시 안정적으로 사용 가능"을 의미하지 않음. 백엔드는 추가 후 자동으로 "할당량 갱신"을 트리거하고, Proxy 실행 시 토큰 풀 리로드를 시도하여 변경 즉시 적용.
다음 두 가지 신호로 확인:
- 계정이 목록에 표시되고 이메일 표시됨 (이메일은 백엔드
get_user_info에서 옴, 입력한 email 아님). - 계정 할당량/구독 정보 갱신 시작 (백엔드는 자동으로
internal_refresh_account_quota호출).
예상 화면: 추가 후 수동으로 새로고침할 필요 없음, 계정에 할당량 정보 표시 시작 (성공 여부는 실제 UI 표시 기준).
체크포인트 ✅
- 계정 목록에서 새 계정의 이메일 확인 가능
- "loading" 상태로 너무 오래 머물지 않음 (OAuth 콜백 완료 후 빨리 마무리되어야 함)
- Proxy 실행 중인 경우, 새 계정이 빠르게 스케줄링에 참여 (백엔드는 리로드 시도)
흔한 오류
1) OAuth에서 "Refresh Token을 가져오지 못함" 메시지
백엔드는 start_oauth_login/complete_oauth_login에서 refresh_token 존재 여부를 명시적으로 확인; 존재하지 않으면 해결 방법이 포함된 오류 메시지 반환 (source/lbjlaq/Antigravity-Manager/src-tauri/src/commands/mod.rs:45-56 참조).
소스 코드의 해결 방법:
https://myaccount.google.com/permissions열기- Antigravity Tools의 액세스 권한 취소
- 애플리케이션으로 돌아가 OAuth 다시 진행
이 수업의 Refresh Token 채널로 전환할 수도 있음.
2) 브라우저에서 localhost refused to connect 메시지
OAuth 콜백은 브라우저가 로컬 콜백 주소를 요청해야 함. 실패율을 낮추기 위해 백엔드는:
127.0.0.1과::1을 동시에 수신 대기 시도- 둘 다 사용 가능할 때만
localhost사용, 그렇지 않으면 강제로127.0.0.1또는[::1]사용
해당 구현은 source/lbjlaq/Antigravity-Manager/src-tauri/src/modules/oauth_server.rs:53-113 참조.
3) 다른 탭으로 전환하면 OAuth 준비 취소
대화상자가 OAuth에서 다른 탭으로 전환하면, 프론트엔드는 cancelOAuthLogin()을 호출하고 URL을 비움 (AddAccountDialog.tsx:127-136 참조).
권한 부여 중인 경우, 탭을 전환하지 마세요.
4) Refresh Token의 올바른/잘못된 예시
| 예시 | 인식 여부 | 원인 |
|---|---|---|
1//0gAbC... | ✓ | 1// 접두사 규칙 준수 (AddAccountDialog.tsx:215-219 참조) |
ya29.a0... | ✗ | 프론트엔드 추출 규칙 불일치, 잘못된 입력으로 간주됨 |
이 수업 요약
- OAuth: "빠름"에 적합, 링크를 복사하여 자주 사용하는 브라우저에서 열고 자동/수동으로 마무리 지원
- Refresh Token: "안정"과 "마이그레이션 가능"에 적합, 텍스트/JSON에서
1//...일괄 추출 지원 refresh_token을 얻을 수 없을 때, 오류 메시지에 따라 권한 취소 후 재시도하거나 Refresh Token 채널로 전환
다음 수업 예고
다음 수업에서는 더 확실한 작업을 수행합니다: 계정 풀을 "마이그레이션 가능 자산"으로 변환.
부록: 소스 코드 참조
확장하여 소스 코드 위치 보기
업데이트 시간: 2026-01-23
| 기능 | 파일 경로 | 행 번호 |
|---|---|---|
| Accounts 페이지에 추가 대화상자 마운트 | src/pages/Accounts.tsx | 267-731 |
| OAuth URL 미리 생성 + 콜백 이벤트 자동 마무리 | src/components/accounts/AddAccountDialog.tsx | 49-125 |
OAuth 콜백 이벤트가 completeOAuthLogin() 트리거 | src/components/accounts/AddAccountDialog.tsx | 67-109 |
| Refresh Token 일괄 분석 및 중복 제거 | src/components/accounts/AddAccountDialog.tsx | 185-268 |
| 프론트엔드 Tauri commands 호출 (add/OAuth/cancel) | src/services/accountService.ts | 5-91 |
| 백엔드 add_account: email 무시, refresh_token으로 실제 이메일 가져와서 저장 | src-tauri/src/commands/mod.rs | 19-60 |
| 백엔드 OAuth: refresh_token 누락 확인 및 권한 취소 해결 방법 제공 | src-tauri/src/commands/mod.rs | 38-79 |
| OAuth 콜백 server: IPv4/IPv6 동시 수신 및 redirect_uri 선택 | src-tauri/src/modules/oauth_server.rs | 43-113 |
| --- | --- | --- |
핵심 이벤트 이름:
oauth-url-generated: 백엔드에서 OAuth URL 생성 후 프론트엔드로 전송 (oauth_server.rs:250-252참조)oauth-callback-received: 백엔드에서 콜백 수신 및 code 분석 후 프론트엔드에 알림 (oauth_server.rs:177-180/oauth_server.rs:232-235참조)
핵심 명령:
prepare_oauth_url: 권한 부여 링크 미리 생성 및 콜백 수신 시작 (src-tauri/src/commands/mod.rs:469-473참조)start_oauth_login: 기본 브라우저 열기 및 콜백 대기 (src-tauri/src/commands/mod.rs:339-401참조)complete_oauth_login: 브라우저 열지 않고, 콜백만 대기하여 토큰 교환 완료 (src-tauri/src/commands/mod.rs:405-467참조)add_account: refresh_token으로 계정 저장 (src-tauri/src/commands/mod.rs:19-60참조)