OAuth 2.0

Published on: September 05, 2025

Tags: #oauth-2.0 #security


Basic OAuth 2.0 Flow

sequenceDiagram
    title OAuth 2.0 Authorization Code Flow (Detailed)
    participant C as Client
    participant O as Resource Owner
    participant A as Authorization Server
    participant R as Resource Server

    C->>O: Authorization Request (client_id, redirect_uri, scope)
    O->>A: Grants consent
    A-->>C: Authorization Code (via redirect)
    C->>A: Access Token Request (authorization_code, client_id, client_secret)
    A-->>C: Access Token
    C->>R: API Request (with Access Token)
    R-->>C: Protected Resource

OAuth 2.0 with PKCE (Proof Key for Code Exchange)

sequenceDiagram
    participant User
    participant Mobile App
    participant STS
    participant API

    %% --- Steps 1-8 are the same ---
    User->>Mobile App: 1. Click login link.
    loop challenge
        Mobile App->>Mobile App: 2. Generate code verifier and code challenge.
    end
    Mobile App->>STS: 3. Authorization code request and code challenge to authorize.
    STS->>User: 4. Redirect to login/authorization prompt.
    User->>STS: 5. Authenticate and consent
    STS->>Mobile App: 6. Authorize code.
    Mobile App->>STS: 7. Authorization code and code verifier to OAuth token.
    loop validate
        STS->>STS: 8. Validate code verifier and challenge.
    end

    %% --- Refined Steps 9-12 ---
    STS->>Mobile App: 9. ID token and access token.
    User->>Mobile App: 10. Initiates request for user data.
    Mobile App->>API: 11. Request user data with access token.
    API->>Mobile App: 12. Response with user data.
    Mobile App->>User: 13. Display data.

Basic OAuth 2.0 Flow with GitHub

sequenceDiagram
    participant User's Browser
    participant Our Application Backend
    participant GitHub Authorization Server
    participant GitHub API Server
    participant Our Database

    %% === Phase 1: User initiates login and is redirected ===

    User's Browser->>Our Application Backend: GET /api/login/github
    activate Our Application Backend
    note right of Our Application Backend: Redirects to GitHub's auth URL with our client_id.
    Our Application Backend-->>User's Browser: HTTP 302 Redirect to github.com/login/oauth/authorize
    deactivate Our Application Backend

    %% === Phase 2: User authorizes the application on GitHub ===

    User's Browser->>GitHub Authorization Server: Follows redirect
    activate GitHub Authorization Server
    note over User's Browser, GitHub Authorization Server: User sees the consent screen, logs into GitHub if necessary, and clicks "Authorize".
    note right of GitHub Authorization Server: GitHub generates a temporary authorization code.
    GitHub Authorization Server-->>User's Browser: HTTP 302 Redirect to our callback URL with the code.
(e.g., /api/auth/github/callback?code=xyz) deactivate GitHub Authorization Server %% === Phase 3: Backend exchanges the code for an access token === User's Browser->>Our Application Backend: Follows redirect to our callback URL activate Our Application Backend note over Our Application Backend: Now the backend takes over. The browser just waits. Our Application Backend->>GitHub Authorization Server: POST /login/oauth/access_token (server-to-server)
{ code, client_id, client_secret } activate GitHub Authorization Server note right of GitHub Authorization Server: Validates code and client credentials. GitHub Authorization Server-->>Our Application Backend: Return { "access_token": "gh_user_token" } deactivate GitHub Authorization Server %% === Phase 4: Backend fetches user info and creates internal session === Our Application Backend->>GitHub API Server: GET /user (server-to-server)
(Authorization: Bearer gh_user_token) activate GitHub API Server GitHub API Server-->>Our Application Backend: Return User Profile (JSON) deactivate GitHub API Server note right of Our Application Backend: Now, work with our own database. Our Application Backend->>Our Database: Find or Create user record by github_id activate Our Database Our Database-->>Our Application Backend: Return internal User object deactivate Our Database note right of Our Application Backend: Create OUR OWN internal JWT for this user. Our Application Backend-->>User's Browser: HTTP 302 Redirect to /api/dashboard?token=our_internal_jwt deactivate Our Application Backend User's Browser->>Our Application Backend: Follows final redirect to dashboard Note over User's Browser: Login is complete. Browser now has our internal JWT.

OAuth 2.0 Flow with PKCE with GitHub

sequenceDiagram
    participant User's Browser
    participant Our Application Backend
    participant GitHub Authorization Server
    participant GitHub API Server
    participant Our Database

    %% === Phase 1: User initiates login, PKCE verifier/challenge are created ===

    User's Browser->>Our Application Backend: GET /api/login/github
    activate Our Application Backend
    note right of Our Application Backend: Generate code_verifier and code_challenge.
    note right of Our Application Backend: Store code_verifier in the user's session.
    note right of Our Application Backend: Redirects to GitHub's auth URL with client_id and code_challenge.
    Our Application Backend-->>User's Browser: HTTP 302 Redirect to github.com/login/oauth/authorize?code_challenge=...
    deactivate Our Application Backend

    %% === Phase 2: User authorizes the application on GitHub ===

    User's Browser->>GitHub Authorization Server: Follows redirect
    activate GitHub Authorization Server
    note over User's Browser, GitHub Authorization Server: User sees the consent screen, logs into GitHub if necessary, and clicks "Authorize".
    note right of GitHub Authorization Server: GitHub stores the code_challenge and generates a temporary authorization code.
    GitHub Authorization Server-->>User's Browser: HTTP 302 Redirect to our callback URL with the code.
(e.g., /api/auth/github/callback?code=xyz) deactivate GitHub Authorization Server %% === Phase 3: Backend exchanges the code and verifier for an access token === User's Browser->>Our Application Backend: Follows redirect to our callback URL activate Our Application Backend note over Our Application Backend: The backend retrieves the code_verifier from the session. Our Application Backend->>GitHub Authorization Server: POST /login/oauth/access_token (server-to-server)
{ code, client_id, client_secret, code_verifier } activate GitHub Authorization Server note right of GitHub Authorization Server: Validates code, client credentials, and verifies that code_verifier matches the original code_challenge. GitHub Authorization Server-->>Our Application Backend: Return { "access_token": "gh_user_token" } deactivate GitHub Authorization Server %% === Phase 4: Backend fetches user info and creates internal session === Our Application Backend->>GitHub API Server: GET /user (server-to-server)
(Authorization: Bearer gh_user_token) activate GitHub API Server GitHub API Server-->>Our Application Backend: Return User Profile (JSON) deactivate GitHub API Server note right of Our Application Backend: Now, work with our own database. Our Application Backend->>Our Database: Find or Create user record by github_id activate Our Database Our Database-->>Our Application Backend: Return internal User object deactivate Our Database note right of Our Application Backend: Create OUR OWN internal JWT for this user. Our Application Backend-->>User's Browser: HTTP 302 Redirect to /api/dashboard?token=our_internal_jwt deactivate Our Application Backend User's Browser->>Our Application Backend: Follows final redirect to dashboard Note over User's Browser: Login is complete. Browser now has our internal JWT.

Share this post

Share on X  •  Share on LinkedIn  •  Share via Email