Skip to content

victorbecerragit/oauth2-learning-lab

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

OAuth2 Learning Lab πŸ”

A complete, self-contained OAuth2 implementation demonstrating modern authentication flows with practical examples. Perfect for learning how OAuth2, JWT tokens, and PKCE work in a real-world scenario.

OAuth2 Flow Docker React Go

🎯 What You'll Learn

This project demonstrates:

  • βœ… OAuth2 Authorization Code Flow with PKCE (Proof Key for Code Exchange)
  • βœ… JWT Token generation, validation, and RSA-256 signature verification
  • βœ… CSRF Protection via state parameter validation
  • βœ… Refresh Tokens for extended sessions
  • βœ… CORS configuration for cross-origin requests
  • βœ… JWT Decoder to inspect token claims and structure
  • βœ… Multi-service Architecture (IDP, Backend API, Frontend)

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     OAuth2 Learning Lab                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                               β”‚
β”‚  Frontend (React)          Backend (Go)          IDP (Go)   β”‚
β”‚  Port 3000                 Port 8081              Port 8080  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚ Login Page   β”‚         β”‚ /callback    β”‚      β”‚/authorizeβ”‚ β”‚
β”‚  β”‚ Dashboard    β”‚         β”‚ /api/profile │◄────►│ /token   β”‚ β”‚
β”‚  β”‚ Token        │────────►│ /logout      β”‚      β”‚ /userinfoβ”‚ β”‚
β”‚  β”‚ Debugger     β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         JWT Validator         SQLite DB   β”‚
β”‚                           CORS Handler          RSA Keys    β”‚
β”‚                                                  β”‚           β”‚
β”‚                                                  JWKS        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸš€ Quick Start

Prerequisites

  • Docker & Docker Compose
  • Make (or run commands manually)
  • Modern web browser

Setup (1 minute)

# Clone the repository
git clone https://github.com/yourusername/oauth2-learning-lab.git
cd oauth2-learning-lab

# Generate RSA keys for JWT signing
make generate-keys

# Build Docker images
make build

# Start all services
make up

# View logs
make logs

Access the Application

Service URL Purpose
Frontend http://localhost:3000 React app - Click "Log in with OAuth2"
Backend API http://localhost:8081 REST API - /callback, /api/profile
IDP Server http://localhost:8080 OAuth2 Identity Provider
IDP Login http://localhost:8080/login Test user login form
JWKS Endpoint http://localhost:8080/.well-known/jwks.json Public keys for verification

πŸ“‹ OAuth2 Flow Walkthrough

1. User Initiates Login

User clicks "Log in with OAuth2"
    ↓
Frontend generates PKCE code_challenge
    ↓
Redirects to IDP: /oauth2/authorize?client_id=...&code_challenge=...&state=...

2. Authorization (Auto-approved for POC)

IDP validates client and redirect_uri
    ↓
Creates authorization code
    ↓
Redirects back to Frontend: /callback?code=xxx&state=yyy

3. Code Exchange

Frontend sends code to Backend: /callback?code=xxx&code_verifier=...
    ↓
Backend exchanges code with IDP: POST /oauth2/token
    ↓
IDP verifies PKCE and issues JWT token
    ↓
Backend returns token to Frontend

4. Access Protected Resources

Frontend calls: GET /api/profile with Authorization: Bearer <token>
    ↓
Backend validates JWT signature using IDP's public keys
    ↓
Returns user profile data

πŸ”‘ Test Credentials

Test Users (IDP Login at http://localhost:8080/login)

OAuth Clients

  • Frontend Client: myshop-frontend (no secret for SPA)
  • Backend Client: myshop-backend with secret backend-secret-change-me

πŸ“Š JWT Token Inspection

Once logged in, navigate to the Dashboard and click "Show Token Details" to see:

{
  "iss": "http://idp:8080",           // Issuer
  "sub": "user-001",                  // Subject (User ID)
  "aud": "myshop-frontend",           // Audience
  "email": "[email protected]",        // Email claim
  "name": "Demo User",                // Name claim
  "scope": "openid profile email",    // Scopes granted
  "iat": 1706702449,                  // Issued At
  "exp": 1706706049,                  // Expiration
  "alg": "RS256"                      // Algorithm
}

πŸ› οΈ API Endpoints

Frontend ↔ Backend

Method Endpoint Purpose
GET /health Health check
GET /callback?code=...&code_verifier=...&redirect_uri=... OAuth callback handler
GET /api/profile Get user profile (requires Bearer token)
GET /api/userinfo Get user info (requires Bearer token)
GET /logout Clear session

Backend ↔ IDP

Method Endpoint Purpose
GET /oauth2/authorize?client_id=...&code_challenge=... Start authorization
POST /oauth2/token Exchange code for token
POST /oauth2/refresh Refresh access token
GET /oauth2/userinfo Get user info from token
GET /.well-known/jwks.json Get public keys for verification

πŸ“ Project Structure

oauth2-learning-lab/
β”œβ”€β”€ frontend/                    # React SPA
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.js         # OAuth2 flow implementation
β”‚   β”‚   β”‚   └── tokenDecoder.js # JWT decoder utility
β”‚   β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”‚   β”œβ”€β”€ ProtectedRoute.jsx
β”‚   β”‚   β”‚   └── TokenDebugger.jsx  # πŸ†• Token inspection
β”‚   β”‚   └── pages/
β”‚   β”‚       β”œβ”€β”€ Login.jsx
β”‚   β”‚       β”œβ”€β”€ Callback.jsx
β”‚   β”‚       └── Dashboard.jsx
β”‚   β”œβ”€β”€ package.json
β”‚   └── Dockerfile
β”‚
β”œβ”€β”€ backend/                     # Go REST API
β”‚   β”œβ”€β”€ main.go                 # API server
β”‚   β”œβ”€β”€ handlers/
β”‚   β”‚   β”œβ”€β”€ auth.go            # OAuth callback & token exchange
β”‚   β”‚   β”œβ”€β”€ profile.go         # User profile endpoint
β”‚   β”‚   └── cors.go            # CORS middleware
β”‚   β”œβ”€β”€ middleware/
β”‚   β”‚   └── jwt..go            # JWT validation
β”‚   └── Dockerfile
β”‚
β”œβ”€β”€ idp/                         # Identity Provider (OAuth2 Server)
β”‚   β”œβ”€β”€ main.go
β”‚   β”œβ”€β”€ auth/
β”‚   β”‚   β”œβ”€β”€ jwt.go             # JWT creation & signing
β”‚   β”‚   └── crypto.go          # PKCE functions
β”‚   β”œβ”€β”€ handlers/
β”‚   β”‚   β”œβ”€β”€ authorize.go       # Authorization endpoint
β”‚   β”‚   β”œβ”€β”€ token.go           # Token endpoint
β”‚   β”‚   └── login.go           # Login form (new!)
β”‚   β”œβ”€β”€ storage/
β”‚   β”‚   └── sqlite.go          # Authorization codes & tokens
β”‚   └── Dockerfile
β”‚
β”œβ”€β”€ scripts/
β”‚   └── generate-keys.sh        # Generate RSA keypair
β”‚
β”œβ”€β”€ secrets/
β”‚   β”œβ”€β”€ private.pem             # Private key (sign tokens)
β”‚   └── public.pem              # Public key (verify tokens)
β”‚
β”œβ”€β”€ docker-compose.yaml         # Multi-container setup
β”œβ”€β”€ makefile                    # Convenient commands
β”œβ”€β”€ ENHANCEMENTS.md             # Feature details
└── README.md                   # This file

πŸŽ“ Learning Concepts

PKCE (Proof Key for Code Exchange)

Why it matters: Prevents authorization code interception attacks in SPAs

  • Frontend generates random code_verifier (43 characters)
  • SHA256 hash β†’ code_challenge
  • Code exchange requires original code_verifier
  • IDP verifies: SHA256(verifier) == challenge

CSRF Protection

  • Frontend generates random state parameter
  • Stores in sessionStorage
  • On callback, verifies state matches
  • Prevents attackers from hijacking OAuth flow

JWT Token Structure

header.payload.signature

Header (encoded):   {"alg":"RS256","typ":"JWT","kid":"default"}
Payload (encoded):  {"iss":"...","sub":"...","email":"...","exp":...}
Signature (crypto): RSA256(header.payload, private_key)

RSA-256 Verification

  • IDP signs tokens with private key
  • Backend verifies with IDP's public key
  • Backend fetches public keys from JWKS endpoint
  • Can verify token without trusting network

πŸ”§ Development Commands

make help              # Show all commands
make generate-keys    # Generate RSA keypair
make build            # Build all Docker images
make up              # Start all services
make down            # Stop all services
make logs            # View service logs
make clean           # Remove volumes and containers
make test            # Run tests (if available)

🌐 Docker Compose Services

Services:
  - idp        (port 8080)  - OAuth2 Identity Provider
  - backend    (port 8081)  - Backend API
  - frontend   (port 3000)  - React SPA

Volumes:
  - idp_data   - SQLite database for authorization codes
  - secrets/   - RSA keys for signing

Networks:
  - oauth2     - Internal network for service communication

πŸ”’ Security Considerations

βœ… Implemented

  • JWT signature verification with RSA-256
  • PKCE for authorization code flow
  • State parameter for CSRF protection
  • CORS configuration
  • Bearer token validation
  • HTTPOnly cookies ready for refresh tokens

⚠️ Not for Production

This is a learning project. Production requirements:

  • HTTPS/TLS for all endpoints
  • Database encryption for sensitive data
  • Rate limiting on auth endpoints
  • Password hashing (bcrypt/scrypt)
  • Session management & timeout
  • Token revocation lists
  • Comprehensive logging & monitoring
  • Input validation & sanitization

πŸ“š Resources to Learn More

🎨 Features

Core OAuth2

  • Authorization Code Flow
  • PKCE (Proof Key for Code Exchange)
  • JWT Token Generation & Validation
  • Refresh Tokens
  • JWKS (JSON Web Key Set)
  • CORS Configuration

User Experience

  • Login form at IDP
  • Dashboard with user profile
  • Logout functionality
  • State validation (CSRF protection)
  • Token debugger/inspector
  • Error handling

Developer Experience

  • Docker Compose setup
  • Health checks
  • Detailed logging
  • Makefile commands
  • Token inspection UI
  • Comprehensive README

πŸš€ Future Enhancements

  • User registration endpoint
  • Password authentication
  • Consent screen
  • Scope selection
  • Silent refresh (automatic token renewal)
  • Rate limiting
  • Multi-factor authentication
  • Social login (Google, GitHub)
  • Database migrations
  • API documentation (Swagger)

🀝 Contributing

This is an educational project. Feel free to:

  • Fork and modify for learning
  • Add more OAuth2 flows (Implicit, Client Credentials, etc.)
  • Implement additional features
  • Improve documentation
  • Add tests

πŸ“ License

MIT License - Use freely for educational purposes

🎯 Next Steps

  1. Run the project: make up
  2. Access frontend: http://localhost:3000
  3. Click login: Trigger OAuth2 flow
  4. View token: Click "Show Token Details" on dashboard
  5. Explore code: Read through the implementations
  6. Experiment: Modify and test the flows

❓ FAQ

Q: Why is the authorization auto-approved? A: This is a POC. In production, users would see a consent screen.

Q: Can I use this in production? A: No - it's for learning only. Lacks production security measures.

Q: How do I modify the token claims? A: Check idp/handlers/token.go - add claims to the JWT payload.

Q: Why does token verification need the public key? A: RSA public keys verify signatures created with private keys. Backend doesn't trust tokens - it verifies them cryptographically.

Q: What's the difference between PKCE and CSRF state? A: PKCE prevents code interception. State prevents misrouted callbacks. Use both!


Happy Learning! πŸŽ“

For questions or suggestions, open an issue or create a pull request.

Made with ❀️ for OAuth2 learners

About

Demo Repo for learning OAuth2 concepts.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published