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#
Making Your First API Call - Testing authentication