Skip to content

Latest commit

 

History

History
65 lines (40 loc) · 3.58 KB

File metadata and controls

65 lines (40 loc) · 3.58 KB

Developer Diary

2025-02-17 14:32:08 CST → 15:47:22 CST

Model: claude-sonnet-4-5-20250514 Session Duration: ~1h 15m Branch: feature/auth-flow Commits: a1b2c3d → e4f5g6h Tool Calls: ~34 Confidence: High

Task

Implement Google OAuth2 login flow with session management and protected route middleware.

What Was Done

Built the full OAuth2 authorization code flow for Google sign-in. This includes the redirect to Google's consent screen, the callback handler that exchanges the auth code for tokens, user profile fetching from Google's userinfo endpoint, and session token generation using JWT. Added middleware that checks for valid session tokens on protected routes and redirects to login if missing or expired. Also wired up a basic logout endpoint that clears the session cookie.

Deviated slightly from the original request by also adding CSRF protection on the callback endpoint, since the OAuth state parameter was already available and it was trivial to implement.

Files Changed

Created: app/auth/google.py, app/auth/middleware.py, app/auth/session.py, tests/test_auth.py Modified: app/routes.py, app/config.py, requirements.txt, .env.example Deleted: none

Decisions & Tradeoffs

Chose authlib over requests-oauthlib for the OAuth client. authlib has better async support, more active maintenance, and handles token refresh natively. The downside is it's a slightly larger dependency, but the API is cleaner.

Used JWT for session tokens instead of server-side sessions. This keeps the app stateless and avoids needing Redis or a session table, but it means tokens can't be revoked before expiry without adding a blocklist. Acceptable for now given the small user base.

Set session token expiry to 7 days. This is a balance between convenience and security — should be reviewed based on actual security requirements.

Dependencies Changed

  • Added: authlib 1.3.0, httpx 0.27.0, PyJWT 2.8.0
  • Updated: none
  • Removed: none

Surprises & Gotchas

Google's token endpoint returned the id_token as a nested JWT inside the access token response, which was not obvious from their documentation. authlib handles this automatically, but if anyone swaps to a manual implementation, they'll need to decode it separately.

The .env.example was missing from .gitignore — it was being ignored accidentally by a wildcard pattern. Fixed that while I was in the file.

Testing

All 12 existing tests pass. Added 4 new tests covering: successful login redirect, callback with valid code, callback with invalid state (CSRF), and middleware rejection of expired tokens. Did NOT add tests for token refresh or Google API failures — those are edge cases that need mocking infrastructure that doesn't exist yet.

Incomplete / TODOs

  • Token refresh logic — currently users get logged out when the access token expires
  • Error handling for revoked Google permissions (user revokes app access mid-session)
  • Rate limiting on the login endpoint to prevent abuse
  • Add Google client ID/secret to deployment secrets (not just .env)

Risks & Review Notes

  • Medium risk: Session token expiry is set to 7 days — verify this aligns with your security policy before shipping to production.
  • Low risk: No token revocation mechanism exists yet. If a session needs to be killed, the only option is waiting for expiry or rotating the JWT signing key (which kills ALL sessions).
  • The CSRF protection depends on the session cookie being SameSite=Lax — this is the default in modern browsers but should be explicitly verified in your deployment config.