Skip to content

Repository files navigation

jwt-auth-practice

just a simple express app I built to practice jwt authentication and token rotation. it uses prisma and postgres.

features

  • register and login flows
  • short-lived access tokens (15m) and long-lived refresh tokens (7 days)
  • token rotation (deletes the old refresh token when a new one is requested)
  • simple rbac (admin vs user routes)
  • rate limiting on the login route so people don't brute force it
  • input validation with zod

setup

  1. npm install
  2. create a .env file (look at src/config/env.ts for what variables you need)
  3. npx prisma db push
  4. npm run dev to start the server on port 3002
  5. npx jest if you want to run the tests

Program Flow

%%{init: {'theme': 'default'}}%%
sequenceDiagram
    autonumber
    actor Client
    participant API as Express API
    participant DB as PostgreSQL (Prisma)
    
    rect rgb(240, 248, 255)
    Note over Client, DB: Registration & Login
    Client->>API: POST /register (email, password)
    API->>API: Validate input (Zod)
    API->>DB: Check if user exists & Save User (hashed password)
    DB-->>API: User Created
    API-->>Client: 201 Created (User Data)
    
    Client->>API: POST /login (email, password)
    API->>API: Rate Limiting Check (Max 5/15m)
    API->>API: Validate input (Zod)
    API->>DB: Fetch User
    DB-->>API: User Data
    API->>API: Compare passwords
    API->>API: Generate Access Token (15m) & Refresh Token (7d)
    API->>DB: Save Refresh Token
    DB-->>API: Saved
    API-->>Client: 200 OK (AccessToken, RefreshToken)
    end
    
    rect rgb(255, 240, 245)
    Note over Client, DB: Accessing Protected Routes
    Client->>API: GET /profile (Authorization: Bearer AccessToken)
    API->>API: Validate AccessToken (authenticate middleware)
    alt Token Valid
        API-->>Client: 200 OK (Profile Data)
    else Token Expired/Invalid
        API-->>Client: 401 Unauthorized
    end
    
    Client->>API: GET /admin-data (Authorization: Bearer AccessToken)
    API->>API: Validate AccessToken (authenticate)
    API->>API: Check Role (authorize('admin'))
    alt Role is Admin
        API-->>Client: 200 OK (Admin Data)
    else Role is User
        API-->>Client: 403 Forbidden
    end
    end
    
    rect rgb(240, 255, 240)
    Note over Client, DB: Token Rotation Flow
    Client->>API: POST /refresh (RefreshToken)
    API->>API: Validate input (Zod)
    API->>DB: Validate RefreshToken exists
    alt Valid & Exists
        DB-->>API: Token Valid
        API->>DB: Delete Old RefreshToken (Rotation)
        API->>API: Generate New AccessToken & RefreshToken
        API->>DB: Save New RefreshToken
        API-->>Client: 200 OK (New AccessToken, New RefreshToken)
    else Invalid/Reused
        API-->>Client: 403 Forbidden
    end
    end
    
    rect rgb(255, 250, 240)
    Note over Client, DB: Logout Flow
    Client->>API: POST /logout (RefreshToken)
    API->>API: Validate input (Zod)
    API->>DB: Delete RefreshToken
    API-->>Client: 200 OK (Logged out)
    end
Loading

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages