Skip to content

fix(claude): token exchange blocked by Cloudflare managed challenge on console.anthropic.com #1659

Description

@Grivn

Bug Description

cliproxyapi -claude-login fails with a 403 error during OAuth token exchange. The token endpoint at https://console.anthropic.com/v1/oauth/token is protected by a Cloudflare managed challenge that requires JavaScript execution, making it impossible for any programmatic HTTP client (Go, curl, Python, etc.) to complete the request.

Steps to Reproduce

cliproxyapi -claude-login

The browser opens and OAuth authorization at claude.ai succeeds, but the subsequent token exchange POST fails:

[error] [claude.go:187] Token exchange failed: token exchange failed with status 403: <!DOCTYPE html><html lang="en-US"><head><title>Just a moment...</title>...

The same 403 occurs with curl, confirming it's a server-side WAF rule (not a TLS/HTTP fingerprinting issue):

curl -s -o /dev/null -w "%{http_code}" -X POST \
  -H "Content-Type: application/json" \
  -d '{"grant_type":"authorization_code","client_id":"9d1c250a-e61b-44d9-88ed-5944d1962f5e","code":"test"}' \
  "https://console.anthropic.com/v1/oauth/token"
# Returns: 403 (Cloudflare managed challenge HTML)

Root Cause

Cloudflare has enabled a managed challenge (cType: 'managed') on console.anthropic.com that blocks all non-browser requests to /v1/oauth/token. This cannot be bypassed with uTLS fingerprinting or custom headers — it requires real JavaScript execution.

Solution

api.anthropic.com hosts the same OAuth token endpoint at /v1/oauth/token but without the Cloudflare managed challenge:

curl -s -w "\n%{http_code}" -X POST \
  -H "Content-Type: application/json" \
  -d '{"grant_type":"authorization_code","client_id":"9d1c250a-e61b-44d9-88ed-5944d1962f5e","code":"test","state":"test","code_verifier":"test"}' \
  "https://api.anthropic.com/v1/oauth/token"
# Returns: {"error": "invalid_grant", "error_description": "Invalid 'code' in request."} (real OAuth2 error, not Cloudflare)
# HTTP 400

Fix: Change TokenURL in internal/auth/claude/anthropic_auth.go from console.anthropic.com to api.anthropic.com:

TokenURL = "https://api.anthropic.com/v1/oauth/token"

Tested locally with a patched build — login succeeds.

Environment

  • CLIProxyAPI Version: 6.8.20
  • OS: macOS (darwin/arm64)
  • Go: 1.24.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions