Skip to content

Baisayan/authy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Authy - Auth and Session Management

Wanted to learn about auth systems and slowly turned it into a complete auth with session handling, CSRF protection, Redis-backed token management, OTP login verification, email verification, caching, rate limiting, and security-focused architecture.

What this project does

  • Hybrid JWT + Redis session authentication
  • Login with password + Email with OTP verification
  • CSRF protection using double submit cookie pattern
  • HTTP-only secure cookies
  • Mongo injection protection
  • Password hashing with bcrypt
  • User caching in Redis
  • Role-based authorization
  • IP + email based rate limiting
  • Logout with full session revocation
  • Refresh token validation & session tracking

High Level System Architecture

flowchart LR
    Client[Client]
    API[Express API]
    Redis[(Redis)]
    Mongo[(MongoDB)]
    SMTP[SMTP Email Service]
    Client -->|HTTP Requests/Cookies| API
    API -->|Cache / Sessions / OTP / Tokens| Redis
    API -->|Persistent User Data| Mongo
    API -->|Verification & OTP Emails| SMTP
    subgraph Security Layer
        JWT[JWT Access + Refresh]
        CSRF[CSRF Protection]
        Rate[Rate Limiting]
        RBAC[Role Authorization]
    end
    API --> JWT
    API --> CSRF
    API --> Rate
    API --> RBAC
Loading

Registration + Email Verification Flow

sequenceDiagram
    participant U as User
    participant A as API (Express)
    participant R as Redis (Cache)
    participant M as MongoDB
    participant S as SMTP (Gmail)
    U->>A: Register (name, email, password)
    A->>A: Validate & Sanitize Input
    A->>M: Check Existing User
    alt User already exists
        M-->>A: User Found
        A-->>U: Email already in use
    else User valid
        A->>A: Hash Password (bcrypt)
        A->>A: Generate Verification Token
        A->>R: Store temporary user data + token
        A->>S: Send Verification Email
    end
    U->>A: Click Verification Link
    A->>R: Verify token
    alt Token expired
        R-->>A: Token Missing
        A-->>U: Verification expired
    else Token valid
        A->>M: Create User Account
        A->>R: Delete temporary token data
        A-->>U: Account created & Email verified
    end
Loading

Login + OTP Verification Flow

sequenceDiagram
    participant User
    participant API
    participant Redis
    participant MongoDB
    User->>API: Login(email, password)
    API->>API: Validate & sanitize payload
    API->>API: Apply rate limiting
    API->>MongoDB: Find user
    API->>API: Verify bcrypt password
    API->>API: Generate OTP
    API->>Redis: Store OTP with expiry
    API->>API: Send OTP email via SMTP
    User->>API: Verify(email, otp)
    API->>Redis: Validate OTP
    API->>Redis: Delete OTP after usage
    API->>API: Generate access & refresh token
    API->>API: Generate CSRF token
    API->>Redis: Store session & refresh token
    API-->>User: Set secure cookies
Loading

Access + Refresh Token Flow

sequenceDiagram
    participant Client
    participant API
    participant Redis
    Client->>API: Request Protected Route
    API->>API: Verify accessToken JWT
    alt Access Token Valid
        API->>Redis: Validate active_session:userId
        alt Session Active
            API-->>Client: Return Protected Data
        else Session Revoked
            API-->>Client: Clear Cookies + 401
        end
    else Access Token Expired
        Client->>API: POST /refresh
        API->>API: Verify refreshToken JWT
        API->>Redis: Get refresh_token:userId
        API->>Redis: Get active_session:userId
        API->>Redis: Get session:sessionId
        alt Refresh + Session Valid
            API->>Redis: Update session lastActivity
            API->>API: Generate New Access Token
            API-->>Client: Set New accessToken Cookie
        else Invalid Session
            API-->>Client: Clear Cookies
            API-->>Client: 401 Session Expired
        end
    end
Loading

CSRF Protection Flow

sequenceDiagram
    participant C as Client
    participant A as API Middleware
    participant R as Redis
    Note over C, R: CSRF Token issued during Login/Refresh
    C->>A: Request (POST/PUT/DELETE)
    Note right of C: Header: x-csrf-token <br/> Cookie: csrfToken
    A->>A: Extract userId from JWT
    A->>R: GET csrf:userId
    R-->>A: Stored Token
    alt Token Matches
        A->>A: next()
    else Token Missing/Invalid
        A-->>C: 403 Forbidden (CSRF Error)
    end
Loading

Session Lifecycle

stateDiagram-v2
    [*] --> LoggedOut
    LoggedOut --> LoginInitiated : Password Verified
    LoginInitiated --> OTPPending : OTP Sent
    OTPPending --> SessionCreated : OTP Verified
    SessionCreated --> ActiveSession
    ActiveSession --> AccessExpired : Access Token Expires
    AccessExpired --> ActiveSession : Refresh Successful
    ActiveSession --> LogoutRequested : User Logout
    LogoutRequested --> SessionRevoked
    ActiveSession --> ForcedLogout : Login From Another Device
    ForcedLogout --> SessionRevoked
    SessionRevoked --> LoggedOut
Loading

Why this architecture?

This project uses hybrid JWT + Redis session validation instead of fully stateless JWT authentication.

JWTs are used for authentication transport while Redis acts as the source of truth for active sessions.

This allows:

  • session revocation
  • forced logout from another device
  • refresh token invalidation
  • active session tracking
  • short-lived access tokens with secure refresh flow

Redis Usage

Redis handles OTP expiration, temporary email verification state, session validation, refresh token revocation, CSRF token storage and rate limiting

Keys Used

verify:token
otp:email
refresh_token:userId
active_session:userId
session:sessionId
csrf:userId
user:userId
login-rate-limit:ip:email
register-rate-limit:ip:email

Token & Session Configuration

  • Access Token Expiry: 15 minutes
  • Refresh Token Expiry: 7 days
  • OTP Expiry: 5 minutes
  • CSRF Token Expiry: 1 hour
  • Session Storage: Redis

Running Locally

1. Clone repo

git clone https://github.com/Baisayan/authy.git

2. Install dependencies

npm install

3. Setup environment variables

Create .env

PORT=5000

MONGO_URI=your_mongodb_uri
REDIS_URL=your_redis_url

SMTP_USER=your_email
SMTP_PASSWORD=your_app_password

JWT_SECRET=your_jwt_secret
REFRESH_SECRET=your_refresh_secret

4. Start server

npm run dev

Now, you can start testing endpoints with Postman.

Testing Routes

1. Register User

POST: /api/v1/register

{
  "name": "ved",
  "email": "ved@mail.com",
  "password": "password123"
}

Check email for verification link.

2. Verify Email

  • Open link from email. Account gets created.

3. Login

POST: /api/v1/login

{
  "email": "ved@mail.com",
  "password": "password123"
}

OTP gets generated, stored in Redis with expiry, and sent via email.

4. Verify OTP

POST: /api/v1/verify

{
  "email": "ved@example.com",
  "otp": "123456"
}

After success, cookies get set and session gets created

5. Test Protected Route

GET: /api/v1/me

  • Should return user data and session info

6. Test Refresh Token

POST: /api/v1/refresh

  • Should generate new access token

7. Test Logout

POST: /api/v1/logout

  • Send CSRF token in headers:x-csrf-token: <csrf_token>
  • Should clear cookies, revoke session and delete refresh token

About

Auth & Session Management System with RBAC, 2FA, CSRF protection

Resources

Stars

Watchers

Forks

Contributors