Skip to content

Add same-port support for Dev OAuth provider to fix SameSite cookie issues #259

@paskal

Description

@paskal

Problem

The dev OAuth provider runs on a separate port (default 8084) from the main application. Since Chrome 80 (February 2020), browsers treat cookies without explicit SameSite attribute as SameSite=Lax by default. This breaks the dev OAuth flow because:

  1. User visits 127.0.0.1:8080/auth/dev/login - JWT handshake cookie is set on port 8080
  2. Browser redirects to 127.0.0.1:8084/login/oauth/authorize (dev OAuth server)
  3. Dev OAuth redirects back to 127.0.0.1:8080/auth/dev/callback
  4. Cookie is NOT sent because browsers treat different ports as different origins for SameSite purposes

Error: failed to get token - token cookie was not presented: http: named cookie not present

Why this happens

  • Before 2020: Browsers sent cookies without SameSite restrictions
  • After Chrome 80: Cookies default to SameSite=Lax, blocking cross-origin redirects
  • Different ports (8080 vs 8084) = different origins from browser's cookie perspective
  • Setting SameSite=None requires Secure=true which requires HTTPS (not practical for local dev)
  • Setting SameSite=Lax or default doesn't help because modern browsers enforce Lax by default

Proposed Solution

Add an option to run the dev OAuth handler on the same port as the main application using path-based routing instead of port-based separation.

API Changes

  1. Add OAuthBasePath field to Params:
type Params struct {
    // ... existing fields
    OAuthBasePath string // e.g., "/auth/dev/oauth" for same-port mode
}
  1. Add Handler() method to DevAuthServer:
// Handler returns http.Handler for mounting on external router
func (d *DevAuthServer) Handler() http.Handler
  1. Add DevAuthHandler() to Service:
// DevAuthHandler returns handler for same-port mounting
func (s *Service) DevAuthHandler() (http.Handler, error)

Usage (same-port mode)

// Configure with OAuthBasePath
authenticator.AddDevProvider("", 0, "/auth/dev/oauth")

// Get handler and mount on main router
devHandler, _ := authenticator.DevAuthHandler()
router.Mount("/auth/dev/oauth", devHandler)

Backward Compatibility

  • Default behavior unchanged (separate port 8084)
  • Same-port mode is opt-in via OAuthBasePath
  • No breaking changes

References

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