Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

user-service

A user authentication service in Go — focused on getting identity flows right rather than on breadth of features. Modular architecture inspired by Docker (Moby): interface-driven boundaries, one concern per package.

What's in here

Google OIDC sign-in, implemented end to end:

  • Authorization Code flow with PKCE — a per-request verifier (oauth2.GenerateVerifier), challenge on the authorize call, verifier proved at exchange
  • state parameter validated on the callback — closes login-CSRF, where an attacker completes their own authorization and lands the victim in the attacker's account
  • The in-flight exchange is held in a __Host- prefixed cookie with a 5-minute TTLSecure, Path=/, no Domain, so a subdomain can't write it
  • Scopes openid email profile, with the OIDC userinfo endpoint for the identity claims

JWT validation with the signing algorithm pinnedjwt.WithValidMethods([]string{HS256}). Without this, a token presented with alg: none or a swapped algorithm can be accepted as valid; it's the single most commonly missed line in JWT handling.

Session authentication as the alternate path — session tokens are stored hashed in MySQL, not in plaintext, so a database read doesn't hand over live sessions. Cookies are HttpOnly, Secure, SameSite=Lax.

Passwords are bcrypt, via GenerateFromPassword / CompareHashAndPassword.

Routes

POST /auth/signup
POST /auth/login
POST /auth/logout          (session middleware)
GET  /oauth2/login         → redirect to provider
GET  /oauth2/callback      → state check, code exchange, session issue

Scope, honestly

This is a relying party — it consumes an identity provider, it does not issue tokens as an authorization server. Single provider (Google); multi-provider support is stubbed, not built.

It also carries almost no tests — one file, covering the error-type helpers. That's a deliberate scope choice rather than an oversight: this repo exists as a focused study of the identity flows above, and the test discipline I apply to systems I operate lives in my other work (velox runs 29 database-invariant checks in CI on every push; notif-service publishes benchmarks with their failed runs). Read this one for the auth code, not as an example of my testing practice.

Configuration

All secrets come from the environment (envconfig) — nothing is committed:

OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET, OAUTH2_REDIRECT_URL
MYSQL_HOST, MYSQL_PORT, MYSQL_DB, MYSQL_USER, MYSQL_PASSWORD
HOST, PORT, MODE

Run locally

go run ./cmd/server

Go · MySQL · ~3,800 lines

About

User authentication service in Go — Google OIDC sign-in (Authorization Code + PKCE, state-validated callback), JWT with pinned signing algorithm, hashed session tokens, bcrypt credentials.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages