Feat/add file upload oauth scope#1352
Conversation
Align OAuth scopes with upstream Claude Code client which now includes the user:file_upload scope for file upload support. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace charset→base64url double-encoding with standard random bytes→base64url approach to match official client behavior and avoid risk control detection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the Claude OAuth constants and PKCE code verifier generation to better match “official” behavior, aiming to reduce risk-control triggers and add file upload scope support.
Changes:
- Add
user:file_uploadto OAuth scope strings (ScopeOAuth,ScopeAPI). - Change PKCE
code_verifiergeneration to use32random bytes → base64url-no-pad (RFC 7636 style). - Modify
RedirectURIconstant (currently set to an empty string).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
backend/internal/pkg/oauth/oauth.go
Outdated
| AuthorizeURL = "https://claude.ai/oauth/authorize" | ||
| TokenURL = "https://platform.claude.com/v1/oauth/token" | ||
| RedirectURI = "https://platform.claude.com/oauth/code/callback" | ||
| RedirectURI = "" |
There was a problem hiding this comment.
RedirectURI is now an empty string, but it is embedded into the authorization URL and also sent as redirect_uri in Claude OAuth API calls (e.g., token exchange). This will produce requests with redirect_uri= which is very likely to be rejected and break the OAuth flow. Restore a valid redirect URI (previous value) or make it configurable (e.g., passed into BuildAuthorizationURL / service methods and validated as non-empty).
| RedirectURI = "" | |
| // RedirectURI must be a non-empty URL registered with the OAuth provider. | |
| // Update this value to match the redirect URI configured for your deployment. | |
| RedirectURI = "http://localhost/oauth/callback" |
| // GenerateCodeVerifier generates a PKCE code verifier (RFC 7636). | ||
| // Uses 32 random bytes → base64url-no-pad, producing a 43-char verifier. | ||
| func GenerateCodeVerifier() (string, error) { | ||
| const targetLen = 32 | ||
| charsetLen := len(codeVerifierCharset) | ||
| limit := 256 - (256 % charsetLen) | ||
|
|
||
| result := make([]byte, 0, targetLen) | ||
| randBuf := make([]byte, targetLen*2) | ||
|
|
||
| for len(result) < targetLen { | ||
| if _, err := rand.Read(randBuf); err != nil { | ||
| return "", err | ||
| } | ||
| for _, b := range randBuf { | ||
| if int(b) < limit { | ||
| result = append(result, codeVerifierCharset[int(b)%charsetLen]) | ||
| if len(result) >= targetLen { | ||
| break | ||
| } | ||
| } | ||
| } | ||
| bytes, err := GenerateRandomBytes(32) | ||
| if err != nil { | ||
| return "", err | ||
| } | ||
|
|
||
| return base64URLEncode(result), nil | ||
| return base64URLEncode(bytes), nil |
There was a problem hiding this comment.
GenerateCodeVerifier logic changed to a new RFC 7636 generation approach, but there are no unit tests in this package covering verifier properties (min length, base64url charset only, no '=' padding, uniqueness). Given this is security-sensitive and similar PKCE generators elsewhere in the repo have tests, add a small test suite for GenerateCodeVerifier (and optionally GenerateCodeChallenge) to prevent regressions.
将生成Base64编码的机制改成和官方一致 将scope字符串内容改成和官方一致,减少风控机率
逆向结果来自claudecode v2.1.84