This project demonstrates JWT and OAuth2 authentication implementations using TypeScript and Fastify, with in-memory data (no database).
npm install
npm run dev
npm run build
npm start
The server will run on http://localhost:3000
GET /
- Returns information about the API and available endpoints
POST /auth/jwt/login
- Body:
{
"email": "[email protected]",
"password": "password123"
}
- Response:
{
"message": "Login successful",
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 900,
"user": {
"id": "1",
"email": "[email protected]",
"name": "Test User"
}
}
POST /auth/jwt/refresh
- Body:
{
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
- Response:
{
"message": "Token refreshed successfully",
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 900
}
- Note: The old refresh token is invalidated and a new one is returned (single-use refresh tokens)
GET /auth/jwt/protected
- Headers:
Authorization: Bearer <access_token>
POST /auth/jwt/logout
- Headers:
Authorization: Bearer <access_token>
- Body (optional):
{
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
GET /auth/oauth2/login
- Returns simulated authorization URL
GET /auth/oauth2/callback?code=mock_auth_code&state=mock_state
- Response:
{
"message": "OAuth2 login successful",
"access_token": "oauth_access_...",
"refresh_token": "oauth_refresh_...",
"token_type": "Bearer",
"expires_in": 3600,
"user": {
"id": "...",
"email": "[email protected]",
"name": "OAuth User",
"provider": "oauth2"
}
}
POST /auth/oauth2/refresh
- Body:
{
"refresh_token": "oauth_refresh_..."
}
- Response:
{
"message": "Token refreshed successfully",
"access_token": "oauth_access_67890",
"refresh_token": "oauth_refresh_67890",
"token_type": "Bearer",
"expires_in": 3600
}
- Note: The old refresh token is invalidated and a new one is returned (single-use refresh tokens)
GET /auth/oauth2/protected
- Headers:
Authorization: Bearer <oauth_access_token>
POST /auth/oauth2/logout
- Headers:
Authorization: Bearer <oauth_access_token>
GET /protected/test
- Headers:
Authorization: Bearer <any_valid_token>
- Works with both JWT and OAuth2 tokens
# Login
curl -X POST http://localhost:3000/auth/jwt/login \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "password": "password123"}'
# Use the returned access_token
curl -X GET http://localhost:3000/auth/jwt/protected \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# Refresh token
curl -X POST http://localhost:3000/auth/jwt/refresh \
-H "Content-Type: application/json" \
-d '{"refresh_token": "YOUR_REFRESH_TOKEN"}'
# Start OAuth2 process
curl -X GET http://localhost:3000/auth/oauth2/login
# Simulate callback (in production this would be done by the browser)
curl -X GET "http://localhost:3000/auth/oauth2/callback?code=mock_auth_code&state=mock_state"
# Use the returned access_token
curl -X GET http://localhost:3000/auth/oauth2/protected \
-H "Authorization: Bearer YOUR_OAUTH_ACCESS_TOKEN"
# Refresh OAuth2 token
curl -X POST http://localhost:3000/auth/oauth2/refresh \
-H "Content-Type: application/json" \
-d '{"refresh_token": "YOUR_OAUTH_REFRESH_TOKEN"}'
- Access tokens expire in 15 minutes
- Refresh tokens expire in 7 days
- Tokens are signed with HS256
- Refresh tokens are stored in memory for validation
- Single-use refresh tokens (new refresh token generated on each refresh)
- Access tokens expire in 1 hour
- Refresh tokens are persistent until logout
- Tokens are unique and randomly generated
- Simulates Authorization Code Grant flow
- Single-use refresh tokens (new refresh token generated on each refresh)
-
In-Memory Data: All data is stored in memory and will be lost when the server restarts.
-
Test User: There is a pre-registered user for JWT testing:
- Email:
[email protected]
- Password:
password123
- Email:
-
Simulated OAuth2: The OAuth2 flow is simulated for demonstration purposes. In production, you would integrate with real providers like Google, GitHub, etc.
-
Security: This is a demonstration implementation. In production, you should:
- Use hashed passwords (bcrypt)
- Store tokens in a secure database
- Implement rate limiting
- Use HTTPS
- Configure CORS properly
- Use secure secrets for JWT
-
Refresh Tokens: JWT refresh tokens are stored in a Set in memory for validation. In production, use a database.
-
Single-Use Refresh Tokens: Both JWT and OAuth2 implement single-use refresh tokens for enhanced security. Each token refresh invalidates the old refresh token and generates a new one.
- Fastify: Fast and efficient web framework
- TypeScript: Static typing
- @fastify/jwt: JWT plugin
- @fastify/cors: CORS plugin
- @fastify/oauth2: OAuth2 plugin (reference)
src/
βββ middleware/
β βββ auth.ts # Authentication middlewares
βββ routes/
β βββ jwt.ts # JWT routes
β βββ oauth.ts # OAuth2 routes
βββ types/
β βββ auth.ts # TypeScript types
βββ utils/
β βββ database.ts # Database simulation
βββ server.ts # Main server