C.W.K.
Stream
Lesson 02 of 04 · published

Token Refresh 와 loadCodeAssist

~14 min · oauth, refresh-token, load-code-assist

Level 0Spark
0 XP0/35 lessons0/10 achievements
0/140 XP to next level140 XP to go0% complete

OAuth 댄스

표준 Google OAuth: access token 이 ~1 시간 유효. 이후 refresh token 을 oauth2.googleapis.com/token 에 grant_type=refresh_token 으로 POST, 새 access token 받음. 새 expiry persist; 죽기 전에 rotate.

loadCodeAssist — 건너뛸 수 없는 pre-flight

OAuth path 의 첫 generate 호출 전에 loadCodeAssist 호출 필수. 이후 모든 generateContent body 의 project field 에 pass 해야 하는 cloudaicompanionProject string 반환. 건너뛰면 헷갈리는 에러 의 HTTP 500 받음.

OAuth client credential 이 public

Gemini CLI 가 hardcoded client_id, client_secret 으로 ship. Public — CLI 돌리는 누구나 같은 pair 사용. Google 이 secret 아니라 identifier 로 다룸. 너 자신의 OAuth flow 에 사용 가능.

Code

Access token refresh·python
import json, os, time, requests

# Public — same values the Gemini CLI uses
GEMINI_CLI_CLIENT_ID     = '681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com'
GEMINI_CLI_CLIENT_SECRET = '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'

CREDS_PATH = os.path.expanduser('~/.gemini/oauth_creds.json')

def get_access_token():
    with open(CREDS_PATH) as f:
        creds = json.load(f)

    # Refresh if expired (or about to)
    if creds.get('expiry_date', 0) < (time.time() + 60) * 1000:
        resp = requests.post('https://oauth2.googleapis.com/token', data={
            'client_id':     GEMINI_CLI_CLIENT_ID,
            'client_secret': GEMINI_CLI_CLIENT_SECRET,
            'refresh_token': creds['refresh_token'],
            'grant_type':    'refresh_token',
        })
        resp.raise_for_status()
        new = resp.json()
        creds['access_token'] = new['access_token']
        creds['expiry_date']  = int(time.time() * 1000) + new['expires_in'] * 1000
        with open(CREDS_PATH, 'w') as f:
            json.dump(creds, f)

    return creds['access_token']
loadCodeAssist — project string 받기·python
import requests

def load_code_assist(access_token):
    resp = requests.post(
        'https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist',
        headers={
            'Authorization': f'Bearer {access_token}',
            'Content-Type': 'application/json',
        },
        json={
            'cloudaicompanionProject': '',
            'metadata': {
                'ideType':    'IDE_UNSPECIFIED',
                'platform':   'PLATFORM_UNSPECIFIED',
                'pluginType': 'GEMINI',
            },
        },
    )
    resp.raise_for_status()
    return resp.json().get('cloudaicompanionProject')
합치기 — OAuth-authed 호출 bootstrap·python
token   = get_access_token()
project = load_code_assist(token)  # cache this — usually stable per-user

resp = requests.post(
    'https://cloudcode-pa.googleapis.com/v1internal:generateContent',
    headers={
        'Authorization': f'Bearer {token}',
        'Content-Type':  'application/json',
    },
    json={
        'model':   'gemini-2.5-flash',
        'project': project,
        'request': {
            'contents': [{'role': 'user', 'parts': [{'text': 'Hello'}]}],
            'generationConfig': {},
        },
    },
)
print(resp.json()['response']['candidates'][0]['content']['parts'][0]['text'])

External links

Exercise

get_access_token()load_code_assist() 를 작은 Python 스크립트로 처음부터 구현. 너 자신의 ~/.gemini/oauth_creds.json 사용. Flow 확인: refresh 동작, loadCodeAssist 가 project 반환, manual v1internal:generateContent POST 가 text 반환. Gemini CLI 설치 안 했으면 fresh client_secrets 파일에서 OAuth 댄스 작성.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.