Skip to content

a2rp/jwt-access-token-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JWT Access Token API

A minimal backend micro project that demonstrates how to:

  • Issue a JWT access token
  • Verify token using middleware
  • Protect routes
  • Handle invalid or expired tokens

This project intentionally does NOT implement refresh tokens. It focuses only on access token flow.


Tech Stack

  • Node.js
  • Express
  • jsonwebtoken
  • dotenv

Installation

git clone <your-repo-url>
cd jwt-access-token-api
npm install

Environment Variables

Create a .env file in root:

PORT=1198
JWT_SECRET=super_secret_change_me
JWT_EXPIRES_IN=15m

Variable Explanation

  • PORT: Server port
  • JWT_SECRET: Secret key used to sign tokens
  • JWT_EXPIRES_IN: Access token expiry duration (example: 15m, 1h)

Run Server

Development mode:

npm run dev

Production mode:

npm start

Server will start at:

http://localhost:1198

Project Structure

jwt-access-token-api/
│
├── src/
│   └── index.js
│
├── .env
├── .gitignore
├── rest.http
├── package.json
└── README.md

Authentication Flow

  1. Client sends email + password to /auth/login
  2. Server verifies credentials
  3. Server issues JWT access token
  4. Client sends token in Authorization header
  5. Middleware verifies token
  6. Protected route returns user data

No refresh token is used in this demo.


Demo Credentials

Email: admin@example.com
Password: admin123


API Routes


1. Health Check

GET /health

Returns service status.

Response:

{
    "ok": true,
    "service": "jwt-access-token-api",
    "time": "2026-02-13T10:00:00.000Z"
}

2. Login - Issue Access Token

POST /auth/login

Request Body:

{
    "email": "admin@example.com",
    "password": "admin123"
}

Successful Response:

{
    "ok": true,
    "message": "login successful",
    "accessToken": "<JWT_TOKEN>",
    "tokenType": "Bearer",
    "expiresIn": "15m"
}

Invalid Credentials Response:

{
    "ok": false,
    "error": "invalid credentials"
}

Missing Fields Response:

{
    "ok": false,
    "error": "email and password are required"
}

3. Protected Route

GET /me

Header:

Authorization: Bearer <JWT_TOKEN>

Successful Response:

{
    "ok": true,
    "user": {
        "sub": "user_001",
        "email": "admin@example.com",
        "role": "admin",
        "iat": 1700000000,
        "exp": 1700000900
    }
}

Invalid or Expired Token Response:

{
    "ok": false,
    "error": "invalid or expired token"
}

How Token Works

When user logs in:

  • Payload is created
  • Token is signed using JWT_SECRET
  • Expiry is added automatically
  • Client stores token
  • Client sends token in Authorization header

Middleware verifies:

  • Signature is valid
  • Token not expired
  • Extracts payload
  • Attaches payload to req.user

Security Notes

  • JWT_SECRET must never be committed
  • Always use strong secret in production
  • Use HTTPS in real deployments
  • Do not store sensitive data in token payload

Learning Objectives

This micro project demonstrates:

  • Stateless authentication
  • Token signing and verification
  • Express middleware for route protection
  • Basic API structure
  • Environment configuration

Future Improvements

  • Add refresh token flow
  • Add logout with token blacklist
  • Add RBAC role middleware
  • Add rate limiter
  • Move auth middleware to separate file
  • Add proper folder structure

License

MIT

About

Minimal JWT access token issue and verification API using Express. Demonstrates stateless authentication without refresh tokens.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors