DEV Community

P VIKRAM KISHORE
P VIKRAM KISHORE

Posted on

Building a Production-Grade OAuth 2.1 + OpenID Connect Authorization Server from Scratch

One of the biggest projects I worked on during my vacation wasn't a bug bounty report or a cloud project.

It was building my own OAuth 2.1 + OpenID Connect Authorization Server.

GITHUB : https://github.com/Waterbottles792/OAuth-App

Like many developers, I'd integrated "Login with Google" or worked with JWTs before, but I realized I never truly understood what happened behind the scenes.

Questions like these kept coming up:

How does an authorization code become an access token?
Why is PKCE mandatory?
Why are refresh tokens rotated?
Why do identity providers expose a JWKS endpoint?
How are ID tokens different from access tokens?
Why are some authentication systems much more secure than others?

Instead of reading another article, I decided to build the entire system myself.

The Goal

Rather than creating a simple authentication service, I wanted to implement something that closely follows the OAuth 2.1 and OpenID Connect specifications while making security the primary design goal.

Every feature was built only after understanding the threat it was designed to prevent.

What I Built

The project includes:

OAuth 2.1 Authorization Server
OpenID Connect Identity Provider
Authorization Code Flow with mandatory PKCE (S256)
JWT Access Tokens and ID Tokens
UserInfo Endpoint
JWKS Endpoint
OpenID Discovery (/.well-known/openid-configuration)
Client Registry
User Consent Management
Token Introspection
Token Revocation
MFA Support
Redis-backed Server Sessions
Audit Logging
Security Alerting
Zero-downtime Signing Key Rotation

The backend is built with Node.js, Express, and TypeScript, while the frontend uses Next.js. PostgreSQL stores persistent data, and Redis handles sessions and caching.

Security Decisions

The most valuable part of the project wasn't adding features—it was understanding why modern identity systems make certain security decisions.

Some examples include:

Passwords and client secrets are hashed using Argon2id rather than weaker hashing algorithms.
JWTs are signed using RS256 with asymmetric keys, eliminating algorithm confusion issues associated with insecure configurations.
Authorization Code Flow is the only supported grant type, with PKCE (S256) required for every authorization request.
Refresh tokens are single-use and automatically rotated. Any attempt to reuse an old refresh token revokes the entire token family.
Redirect URIs require an exact match, preventing wildcard-based attacks.
Sessions are stored server-side using Redis with secure, HttpOnly cookies.
Authorization codes and refresh tokens are never stored in plaintext—they're stored as SHA-256 hashes.

Implementing these decisions forced me to understand the attacks they are designed to prevent, rather than simply copying configurations from tutorials.

What I Learned

Before this project, authentication felt like a collection of APIs and libraries.

Now I understand it as a sequence of carefully designed security protocols.

I learned how:

Identity and authorization are separate concerns.
PKCE protects public clients from authorization code interception.
JWT signing and key rotation work in production.
Refresh token rotation limits the impact of token theft.
OpenID Connect builds an identity layer on top of OAuth.
Proper session management is just as important as token security.

Most importantly, I learned that building secure authentication is about understanding standards—not inventing your own.

Looking Ahead

This project was one of the most challenging things I built during my vacation, but it completely changed the way I think about authentication and identity.

There are still many areas I want to explore, including federation, SAML, passkeys (WebAuthn), and advanced identity architectures.

For now, I'm happy to have built a strong foundation by implementing OAuth 2.1 and OpenID Connect from the ground up.

If you're learning application security or backend development, I highly recommend building an authentication system yourself. You'll gain a much deeper appreciation for the standards and the security decisions behind them than you ever will by simply consuming an authentication library.

Thanks for reading.

Top comments (0)