proxy-shield
v1.0.0
Published
Universal API request protection with obfuscated tokens for both frontend and backend applications
Maintainers
Readme
Proxy Shield
Universal API request protection with obfuscated tokens. Protects your APIs from unauthorized access using cryptographic tokens generated on both client and server with a shared secret key.
Features
- 🛡️ API Protection: Secure your APIs with obfuscated tokens
- 🔑 Shared Secret: Client and server use the same secret key
- ⚡ High Performance: Fast token generation and verification
- 🌐 Universal: Works in Node.js and browsers
- 🚀 Easy Integration: Simple middleware like rate limiters
- 📦 Zero Dependencies: No external dependencies
Installation
```bash npm install proxy-shield ```
Quick Start
Frontend (Simple Usage)
```typescript import { generateToken } from 'proxy-shield';
// Generate a token using the shared secret const token = await generateToken('your-shared-secret-key', 12); // 12 rounds
// Use in fetch requests fetch('/api/data', { headers: { 'X-Proxy-Shield-Token': token } }); ```
Backend (NestJS)
```typescript // app.module.ts import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'; import { proxyShieldMiddleware } from 'proxy-shield';
@Module({ // ... your existing setup }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { // Apply Proxy Shield middleware (same pattern as rate limiter) consumer.apply(proxyShieldMiddleware({ secretKey: process.env.PROXY_SHIELD_SECRET_KEY, tokenRounds: 12, maxSkewMs: 5000, skipRoutes: ['/health', '/auth/login'], })).forRoutes('*'); } } ```
Backend (Express)
```typescript import express from 'express'; import { createProxyShieldMiddleware } from 'proxy-shield';
const app = express();
app.use(createProxyShieldMiddleware({ secretKey: process.env.PROXY_SHIELD_SECRET_KEY, tokenRounds: 12, maxSkewMs: 5000, })); ```
Core Functions
Generate Token (Client-side)
```typescript import { generateToken } from 'proxy-shield';
const secretKey = 'your-shared-secret-key'; const token = await generateToken(secretKey, 12); // 12 rounds
// Use in requests fetch('/api/data', { headers: { 'X-Proxy-Shield-Token': token } }); ```
Verify Token (Server-side)
```typescript import { verifyToken } from 'proxy-shield';
const secretKey = 'your-shared-secret-key'; const token = req.headers['x-proxy-shield-token'];
const isValid = await verifyToken(secretKey, token, 5000); // 5 second tolerance if (!isValid) { return res.status(401).json({ error: 'Invalid token' }); } ```
Configuration
```typescript interface ProxyShieldConfig { secretKey: string; // Required: Shared secret key tokenRounds?: number; // Optional: Hashing rounds (default: 10) maxSkewMs?: number; // Optional: Max time skew (default: 5000) headerName?: string; // Optional: Header name (default: 'X-Proxy-Shield-Token') skipRoutes?: string[]; // Optional: Routes to skip enableLogging?: boolean; // Optional: Debug logging (default: false) } ```
Environment Variables
```bash
Backend
PROXY_SHIELD_SECRET_KEY=your-super-secret-key-here
Frontend (React)
REACT_APP_PROXY_SHIELD_SECRET=your-super-secret-key-here
Frontend (Vue)
VITE_PROXY_SHIELD_SECRET=your-super-secret-key-here ```
Integration Examples
Your Existing NestJS Setup
```typescript // Before export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer.apply(globalRateLimiter).forRoutes('*'); } }
// After - Add Proxy Shield import { proxyShieldMiddleware } from 'proxy-shield';
export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer.apply(globalRateLimiter).forRoutes(''); consumer.apply(proxyShieldMiddleware({ secretKey: process.env.PROXY_SHIELD_SECRET_KEY, tokenRounds: 12, maxSkewMs: 5000, skipRoutes: ['/health', '/metrics'], })).forRoutes(''); } } ```
React Example
```typescript import { generateToken } from 'proxy-shield'; import { useState, useEffect } from 'react';
function UsersList() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true);
useEffect(() => { async function fetchUsers() { try { // Generate token with shared secret const token = await generateToken( process.env.REACT_APP_PROXY_SHIELD_SECRET, 12 );
// Use token in request
const response = await fetch('/api/users', {
headers: {
'X-Proxy-Shield-Token': token
}
});
const data = await response.json();
setUsers(data);
} catch (error) {
console.error('Error fetching users:', error);
} finally {
setLoading(false);
}
}
fetchUsers();}, []);
if (loading) return Loading...;
return ( {users.map(user => ( {user.name} ))} ); } ```
Security
- Strong Secret Keys: Use 32+ character random strings
- Same Configuration: Identical settings on frontend and backend
- Time Skew: 5-10 seconds to handle clock differences
- Skip Public Routes: Health checks, login endpoints
- Environment Variables: Never hardcode secret keys
License
MIT
