GitHub OAuth#

GitHub OAuth implementation for web user authentication with JWT token generation.

OAuth Flow#

        sequenceDiagram
    participant User
    participant Frontend
    participant API
    participant GitHub

    User->>Frontend: Click "Login"
    Frontend->>API: GET /github/login
    API->>API: Generate state token (CSRF protection)
    API-->>Frontend: Redirect to GitHub (with state)
    Frontend->>GitHub: Authorization request
    User->>GitHub: Approve
    GitHub-->>API: Callback with code + state
    API->>API: Verify state token (CSRF check)
    API->>GitHub: Exchange code for token
    GitHub-->>API: Access token
    API->>GitHub: Get user info + org membership
    GitHub-->>API: User profile
    API->>API: Create/update user + assign roles
    API->>API: Generate JWT (30 min expiration)
    API-->>Frontend: Redirect with JWT
    

Configuration#

Required environment variables:

GITHUB_CLIENT_ID=your_oauth_app_id
GITHUB_CLIENT_SECRET=your_oauth_app_secret
GITHUB_ORG_NAME=your_org_name  # Required for org membership check
SECRET_KEY=jwt_signing_key
FRONTEND_URL=http://localhost:8080  # OAuth callback redirect
BACKEND_URL=http://localhost:8000

Optional:

GITHUB_TEAM_ROLE_MAPPING='{"org/admins": "admin", "org/observers": "observer"}'

JWT Generation#

from jose import jwt
from datetime import datetime, timedelta

def create_jwt_token(user: User) -> str:
    payload = {
        "sub": user.username,  # Username in subject
        "exp": datetime.utcnow() + timedelta(minutes=30),  # 30 minute expiration
        "iat": datetime.utcnow()
    }
    return jwt.encode(payload, SECRET_KEY, algorithm="HS256")

Frontend Integration#

// Redirect to OAuth
window.location.href = `${API_URL}/github/login`;

// After callback, extract JWT from URL
const params = new URLSearchParams(window.location.search);
const jwt = params.get('token');

// Store and use
localStorage.setItem('jwt_token', jwt);

// Make authenticated requests
fetch(`${API_URL}/auth/me`, {
  headers: {'Authorization': `Bearer ${jwt}`}
});

Next Steps#