DEV Community

Cover image for Stop Copy-Pasting Auth Logic. Build It Once.
D Abhiram Karanth
D Abhiram Karanth

Posted on

Stop Copy-Pasting Auth Logic. Build It Once.

Authentication is one of those things every dev team rebuilds from scratch. Every. Single. Time.

App A has login? Cool. App B copies it. App C "improves" it. Fast forward six months and you've got:

  • Three different token formats
  • Two apps that don't actually log users out
  • One app that expires tokens after 15 minutes for "security"
  • Zero chance of sanity

There's a better way.

I built Auth-Flow — a centralized authentication service in Go that you build once and reuse everywhere.

GitHub: https://github.com/abhiram-karanth-core/auth-flow


The Problem With Scattered Auth

Here's how most teams handle authentication:

  1. Copy auth code from the last project
  2. Tweak it slightly for "this app's needs"
  3. Ship it
  4. Repeat for the next service

This works... until it doesn't.

Eventually you hit the wall:

  • Can't revoke tokens across services
  • Logout doesn't actually work
  • Every service has different expiration rules
  • Nobody remembers which app stores passwords how

Auth shouldn't be copypasta. It should be infrastructure.


What Auth-Flow Does

Auth-Flow is a standalone service that handles:

  • OAuth 2.0 (starting with Google, easily extensible)
  • JWT minting with proper claims
  • Real logout (yes, actually works)
  • Token revocation via Redis
  • Stateless validation for your other services

Your apps don't handle auth anymore. They just trust this service.


How It Works

Auth-Flow supports two authentication paths:

Option 1: OAuth Flow (Google)

  1. User clicks "Login with Google"
  2. Auth-Flow redirects to Google
  3. Google sends back an auth code
  4. Auth-Flow exchanges it for user info
  5. Auth-Flow mints a signed JWT
  6. Client gets the token

Option 2: Custom Authentication (/mint)

Already verified a user through your own system? Just call /mint:

POST /mint
Content-Type: application/json

{
  "sub": "username",
  "provider": "local",
  "email": "user@example.com"
}
Enter fullscreen mode Exit fullscreen mode

Auth-Flow returns a JWT - no questions asked.

This is the key design decision: Auth-Flow doesn't care how you authenticated the user. It only cares about issuing and revoking tokens consistently.

No passwords stored. No session cookies. Clean.

The Real Problem: Logout

Here's the dirty secret about JWTs: they don't support logout.

JWTs are stateless. You can't "delete" them. Once issued, they're valid until expiration.

Most tutorials ignore this. Real systems can't.

The Fix: Redis + Token IDs

Every JWT gets a unique ID (jti). When someone logs out:

  1. Store the jti in Redis with TTL matching token expiration
  2. Middleware checks Redis on every request
  3. If jti exists in Redis, token is revoked, return 401

Result:

  • Instant logout across all services
  • No central session store
  • Still horizontally scalable

This is the part most auth libraries skip. Auth-Flow handles it out of the box.


Core Endpoints

GET  /auth/{provider}
GET  /auth/{provider}/callback
POST /mint
POST /logout
Enter fullscreen mode Exit fullscreen mode

Your other services just need lightweight middleware:

  • Verify JWT signature
  • Check Redis for revocation
  • Extract user claims

That's it.

Why Go?

Go is perfect for auth infrastructure:

  • Fast startup — runs in milliseconds
  • Low memory — handles thousands of requests on minimal resources
  • Built for concurrency — handles OAuth callbacks + Redis + validation in parallel
  • Simple — the whole service is around 500 lines, easy to audit

Plus: excellent libraries for OAuth, JWT, and Redis. No framework bloat needed.


When Should You Use This?

This pattern makes sense if you have:

  • Multiple backend services (microservices, modular monoliths, etc.)
  • Web + mobile clients
  • Any need for SSO or centralized user management
  • An allergy to reimplementing auth every sprint

Not a fit if:

  • You have one tiny service and that's it
  • You're prototyping and don't care about logout
  • You want to store passwords locally (please don't)

What's Next

Roadmap ideas:

  • Refresh tokens (currently just access tokens)
  • Role-based permissions in JWT claims
  • Support for GitHub, Azure AD, custom OIDC providers
  • Admin API for token introspection
  • Rate limiting on auth endpoints

Final Thoughts

Authentication isn't app logic. It's infrastructure.

Stop rebuilding it. Stop copying it. Build it once, properly, and move on.

Auth-Flow gives you:

  • OAuth out of the box
  • Real logout that actually works
  • One source of truth for tokens
  • Less code in every other service

If you're running distributed systems, this saves time, reduces bugs, and keeps security consistent.

Check it out: https://github.com/abhiram-karanth-core/auth-flow


Got questions? Built something similar? Hate this approach? Drop a comment. I read 'em all.

Top comments (0)