feat(ios/macos): return serverAuthCode for offline access#1
feat(ios/macos): return serverAuthCode for offline access#1proggeramlug wants to merge 1 commit into
Conversation
GIDSignInResult carries a one-time server auth code when a serverClientID is configured (GIDServerClientID). Surface it as `serverAuthCode` on the success result so a backend can exchange it for a refresh token and keep calling Google APIs after the short-lived access token expires. Without this, native clients only ever receive a ~1h access token, so any server-side data sync (e.g. Search Console) breaks once it expires. The interactive iOS + macOS paths both route through handleSignInResult, so both now include the code; silent restore omits it (no new code is issued).
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe Swift iOS bridge's ChangesserverAuthCode in sign-in result
Estimated code review effort🎯 2 (Simple) | ⏱️ ~5 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
What
Surface Google's one-time
serverAuthCodeon the success result ofjs_google_auth_sign_in()(iOS + macOS).GIDSignInResult.serverAuthCodeis populated by the GoogleSignIn SDK whenever aserverClientIDis configured (we already set it fromGIDServerClientIDinloadConfiguration). We just weren't returning it.Why
Native clients currently only ever get a short-lived (~1h) access token. Any server-side data sync — in our case Google Search Console — works right after linking, then breaks once the token expires, because the backend has no refresh token and no way to obtain one.
The standard fix is offline access: the SDK hands the app a
serverAuthCode, the app sends it to the backend, and the backend exchanges it (grant_type=authorization_code, client secret) for a refresh token. This PR exposes the code so that flow is possible.Changes
crate-ios/swift/google_auth_bridge.swiftserializeUser(_:serverAuthCode:)appends"serverAuthCode"to the JSON when non-empty.handleSignInResultpassesresult?.serverAuthCode. Both the iOS (UIViewController) and macOS (NSWindow) interactive paths route throughhandleSignInResult, so both are covered.restorePreviousSignIn) omits it — no new auth code is issued on a silent restore.src/index.ts— addserverAuthCode?: stringto thesuccess: truevariant ofGoogleSignInResult, documented as offline-access / exchange-server-side.Notes
serverClientIDis configured and the SDK returns a code.crate-android) uses Credential Manager, which surfaces an ID token rather than an auth code; offline access there is a separate mechanism (AuthorizationClient) and is out of scope for this PR.Testing
Verified end-to-end in a downstream app (GSC Master): with this change the app receives
serverAuthCode, the backend exchanges it for a refresh token, and Search Console data continues loading after the access token expires (previously the dashboard went empty ~1h after linking).Summary by CodeRabbit
serverAuthCodefield in sign-in results when a server client ID is configured. This authorization code can be securely exchanged on your backend server for refresh tokens, enabling more robust session management and improved authentication workflows.