auth-fingerprint
v1.0.24
Published
Secure fingerprint hashing, signing & integrated HTTP API client with timestamped verification for Node.js
Maintainers
Readme
📦 auth-fingerprint
Secure fingerprint hashing, signing & one-time verification for Node.js. Prevent replay attacks with timestamped signatures. 🔐
✨ Features
- 🔑 HMAC-SHA256 based hashing & verification
- ⏳ Timestamp included (expiry support)
- 🚫 Time-based validation (replay protection)
- 🖥 Works with any object: { ip, browser, os }
- ⚡ Lightweight & dependency-free (only Node.js crypto)
- 🪙 NEW: ERC-20 token operations (balance, transfer, deposit history)
- 💰 NEW: Native ETH transactions with ethers.js integration
- 🔗 NEW: Blockchain RPC utilities and helpers
📦 Installation
npm install auth-fingerprint🎥 Tutorial Video
Watch our comprehensive tutorial to get started quickly with auth-fingerprint:
What you'll learn:
- 🔧 Installation and setup
- 🔑 Basic fingerprint hashing and verification
- ✍️ Digital signature methods
- 🌐 API authentication integration
- 🛡️ Server-side verification
- 💡 Real-world use cases and best practices
Duration: ~15 minutes | Beginner-friendly
🚀 Usage Examples
1. Basic Authentication Setup
const {
hashFingerprint,
verifyFingerprint,
signFingerprint,
verifySignature
} = require("auth-fingerprint");
// Your secret key (store securely in environment variables)
const SECRET_KEY = process.env.AUTH_SECRET || "your-secure-secret-key";
// Device fingerprint from client request
const deviceFingerprint = {
ip: "192.168.1.100",
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
acceptLanguage: "en-US,en;q=0.9",
screenResolution: "1920x1080"
};2. Session Token Generation (Hash Method)
// Generate session token
function createSessionToken(userFingerprint) {
const result = hashFingerprint(userFingerprint, SECRET_KEY);
console.log("Session created:", {
hash: result.hash.substring(0, 16) + "...",
timestamp: new Date(result.timestamp).toISOString(),
expiresIn: "1 minute"
});
return result;
}
const sessionToken = createSessionToken(deviceFingerprint);3. Session Validation
// Validate session token
function validateSession(fingerprint, hash, timestamp) {
const verification = verifyFingerprint(fingerprint, hash, timestamp, SECRET_KEY);
if (verification.success) {
console.log("✅ Session valid for user:", verification.data.ip);
return { valid: true, user: verification.data };
} else {
console.log("❌ Session invalid:", verification.reason);
return { valid: false, reason: verification.reason };
}
}
// Test validation
const validation = validateSession(
deviceFingerprint,
sessionToken.hash,
sessionToken.timestamp
);4. Digital Signatures (Recommended)
// Create signed authentication payload
function createAuthPayload(userFingerprint, userId) {
const payload = signFingerprint({
...userFingerprint,
userId: userId,
action: "login"
}, SECRET_KEY);
console.log("Auth payload created:", {
userId: payload.fingerprint.userId,
signature: payload.signature.substring(0, 16) + "...",
timestamp: new Date(payload.timestamp).toISOString()
});
return payload;
}
// Verify signed payload
function verifyAuthPayload(signedPayload, customTolerance = 300000) { // 5 minutes
const verification = verifySignature(signedPayload, SECRET_KEY, customTolerance);
if (verification.success) {
console.log("✅ Authentication successful for user:", verification.data.userId);
return { authenticated: true, user: verification.data };
} else {
console.log("❌ Authentication failed:", verification.reason);
return { authenticated: false, reason: verification.reason };
}
}
// Example usage
const authPayload = createAuthPayload(deviceFingerprint, "user123");
const authResult = verifyAuthPayload(authPayload);5. Express.js Middleware Integration
const express = require('express');
const app = express();
// Custom authentication middleware
function authMiddleware(req, res, next) {
const authHeader = req.headers['x-auth-signature'];
if (!authHeader) {
return res.status(401).json({ error: 'Missing authentication' });
}
try {
const payload = JSON.parse(Buffer.from(authHeader, 'base64').toString());
const verification = verifySignature(payload, SECRET_KEY, 600000); // 10 minutes
if (verification.success) {
req.user = verification.data;
next();
} else {
res.status(401).json({ error: 'Invalid authentication', reason: verification.reason });
}
} catch (error) {
res.status(400).json({ error: 'Malformed authentication header' });
}
}
// Protected route
app.get('/api/profile', authMiddleware, (req, res) => {
res.json({
message: 'Profile data',
user: req.user.userId,
loginTime: new Date(req.user.timestamp).toISOString()
});
});⚙️ API
hashFingerprint(fingerprint, secret)
Creates a timestamped hash of the fingerprint object.
Parameters:
fingerprint(object) - The fingerprint data (e.g. { ip, browser, os })secret(string) - Secret key for HMAC signing
Returns:
{ hash: string, timestamp: number }- Hash and timestamp
verifyFingerprint(fingerprint, hash, timestamp, secret, tolerance?)
Verifies a fingerprint hash with timestamp validation.
Parameters:
fingerprint(object) - Original fingerprint datahash(string) - Hash to verifytimestamp(number) - Original timestampsecret(string) - Same secret key used for hashingtolerance(number, optional) - Validity window in ms (default: 60000 = 1 minute)
Returns:
{ success: true, data: object }- If verification succeeds{ success: false, reason: "expired" | "mismatch" }- If verification fails
signFingerprint(fingerprint, secret)
Creates a signed payload with fingerprint, timestamp, and signature.
Parameters:
fingerprint(object) - The fingerprint data (e.g. { ip, browser, os })secret(string) - Secret key for HMAC signing
Returns:
{ fingerprint: object, timestamp: number, signature: string }- Complete signed payload
verifySignature(payload, secret, tolerance?)
Verifies a signed payload with timestamp validation.
Parameters:
payload(object) - Signed payload from signFingerprintsecret(string) - Same secret key used for signingtolerance(number, optional) - Validity window in ms (default: 60000 = 1 minute)
Returns:
{ success: true, data: object }- If verification succeeds{ success: false, reason: "expired" | "mismatch" }- If verification fails
🔐 Security Notes
- Default expiry = 1 minute (2000ms)
- Uses timing-safe comparison to prevent timing attacks
- Deterministic serialization ensures consistent hashing
- HMAC-SHA256 provides cryptographic security
🌐 Integrated API Client
The package includes api.js - a complete HTTP client with built-in fingerprint authentication:
Real-World API Authentication
const { API_CALL } = require('auth-fingerprint/api');
const { getDeviceFingerprint } = require('auth-fingerprint/api');
// E-commerce API example
class SecureAPIClient {
constructor(baseURL, apiSecret) {
this.baseURL = baseURL;
this.apiSecret = apiSecret;
}
// Login with device fingerprinting
async login(credentials, req) {
const deviceFingerprint = getDeviceFingerprint(req);
const response = await API_CALL({
method: 'POST',
url: '/auth/login',
baseURL: this.baseURL,
body: {
...credentials,
deviceId: deviceFingerprint.ip + deviceFingerprint.userAgent
},
auth: {
enabled: true,
method: 'signature',
secret: this.apiSecret,
fingerprint: deviceFingerprint
}
});
if (response.success) {
console.log('✅ Login successful:', response.data.user);
return response.data.token;
} else {
throw new Error('Login failed: ' + response.error);
}
}
// Make authenticated requests
async makeSecureRequest(endpoint, data, userFingerprint) {
return await API_CALL({
method: 'POST',
url: endpoint,
baseURL: this.baseURL,
body: data,
auth: {
enabled: true,
method: 'signature',
secret: this.apiSecret,
fingerprint: {
...userFingerprint,
timestamp: Date.now()
}
},
headers: {
'Content-Type': 'application/json',
'X-API-Version': '2.0'
}
});
}
// Get user profile with authentication
async getUserProfile(userId, userFingerprint) {
try {
const response = await this.makeSecureRequest(
`/users/${userId}/profile`,
{ action: 'get_profile' },
userFingerprint
);
return response.data;
} catch (error) {
console.error('Profile fetch failed:', error.message);
return null;
}
}
// Update user settings
async updateSettings(userId, settings, userFingerprint) {
return await this.makeSecureRequest(
`/users/${userId}/settings`,
{ settings, action: 'update_settings' },
userFingerprint
);
}
}
// Usage example
const apiClient = new SecureAPIClient(
'https://api.myapp.com',
process.env.API_SECRET
);
// In your Express route
app.post('/login', async (req, res) => {
try {
const token = await apiClient.login(req.body, req);
res.json({ success: true, token });
} catch (error) {
res.status(401).json({ error: error.message });
}
});Server-side Verification Middleware
const express = require('express');
const {
verifyRequestAuth,
verifyRequestSignature,
authMiddleware,
getDeviceFingerprint
} = require('auth-fingerprint/api');
const app = express();
app.use(express.json());
// Custom security middleware
function securityMiddleware(options = {}) {
return (req, res, next) => {
const fingerprint = getDeviceFingerprint(req);
// Rate limiting by IP
const rateLimitKey = `rate_limit_${fingerprint.ip}`;
// Implement your rate limiting logic here
// Device change detection
if (req.session && req.session.lastFingerprint) {
const lastDevice = req.session.lastFingerprint;
if (lastDevice.userAgent !== fingerprint.userAgent) {
console.log('⚠️ Device change detected for user');
// Implement additional security measures
}
}
req.deviceFingerprint = fingerprint;
next();
};
}
// Apply security middleware
app.use(securityMiddleware());
// Protected routes with different auth methods
app.use('/api/v1/secure', authMiddleware('signature'));
app.use('/api/v1/admin', authMiddleware('hash'));
// Secure endpoint example
app.post('/api/v1/secure/transfer', (req, res) => {
const { amount, recipient } = req.body;
const userDevice = req.authData;
// Log security event
console.log(`💰 Transfer request: ${amount} to ${recipient}`);
console.log(`🔒 From device: ${userDevice.ip} - ${userDevice.userAgent}`);
// Implement transfer logic with additional security checks
if (amount > 1000) {
// Require additional verification for large amounts
return res.status(403).json({
error: 'Large transfer requires additional verification',
requiresVerification: true
});
}
res.json({
success: true,
message: 'Transfer initiated',
transactionId: 'tx_' + Date.now(),
deviceVerified: true
});
});
// Health check with device info
app.get('/api/health', (req, res) => {
res.json({
status: 'healthy',
timestamp: new Date().toISOString(),
device: req.deviceFingerprint
});
});
app.listen(3000, () => {
console.log('🚀 Secure API server running on port 3000');
});📝 Real-World Use Cases
🏦 Banking & Financial Services
// Detect suspicious login attempts
function detectSuspiciousActivity(currentFingerprint, userHistory) {
const lastKnownDevice = userHistory.lastDevice;
const suspiciousFactors = {
newLocation: currentFingerprint.ip !== lastKnownDevice.ip,
newDevice: currentFingerprint.userAgent !== lastKnownDevice.userAgent,
unusualTime: isUnusualLoginTime(new Date()),
rapidRequests: checkRateLimit(currentFingerprint.ip)
};
const riskScore = Object.values(suspiciousFactors).filter(Boolean).length;
if (riskScore >= 2) {
return { requiresVerification: true, riskScore, factors: suspiciousFactors };
}
return { requiresVerification: false, riskScore };
}🛒 E-commerce Security
// Prevent cart manipulation and session hijacking
function secureCheckout(cartData, userFingerprint, sessionToken) {
// Verify session integrity
const sessionValid = verifyFingerprint(
userFingerprint,
sessionToken.hash,
sessionToken.timestamp,
process.env.SESSION_SECRET,
1800000 // 30 minutes
);
if (!sessionValid.success) {
throw new Error('Session expired or invalid');
}
// Additional cart validation
const cartSignature = signFingerprint({
...userFingerprint,
cartTotal: cartData.total,
items: cartData.items.length
}, process.env.CART_SECRET);
return { sessionValid: true, cartSignature };
}🏢 Enterprise API Gateway
// Microservices authentication
class ServiceAuthenticator {
constructor(serviceSecret) {
this.secret = serviceSecret;
}
// Generate service-to-service token
generateServiceToken(serviceId, permissions) {
return signFingerprint({
serviceId,
permissions,
environment: process.env.NODE_ENV
}, this.secret);
}
// Verify incoming service requests
verifyServiceRequest(req) {
const authHeader = req.headers['x-service-auth'];
if (!authHeader) return { valid: false, reason: 'missing_auth' };
try {
const payload = JSON.parse(Buffer.from(authHeader, 'base64').toString());
const verification = verifySignature(payload, this.secret, 300000); // 5 minutes
return verification.success
? { valid: true, service: verification.data }
: { valid: false, reason: verification.reason };
} catch (error) {
return { valid: false, reason: 'invalid_format' };
}
}
}📱 Mobile App Security
// Device binding for mobile apps
function bindDeviceToUser(userId, deviceInfo) {
const deviceFingerprint = {
deviceId: deviceInfo.uniqueId,
platform: deviceInfo.platform,
version: deviceInfo.version,
model: deviceInfo.model
};
const deviceToken = signFingerprint({
userId,
...deviceFingerprint,
bindingTime: Date.now()
}, process.env.DEVICE_SECRET);
// Store device binding in database
return {
deviceToken,
expiresAt: Date.now() + (30 * 24 * 60 * 60 * 1000) // 30 days
};
}🚀 Production Deployment Guide
1. Environment Setup
# Install the package
npm install auth-fingerprint
# Set environment variables
echo "AUTH_SECRET=your-super-secure-secret-key-here" >> .env
echo "API_SECRET=your-api-secret-key-here" >> .env
echo "NODE_ENV=production" >> .env2. Production Server Setup
const express = require('express');
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
const { authMiddleware, getDeviceFingerprint } = require('auth-fingerprint/api');
const app = express();
// Security middleware
app.use(helmet());
app.use(express.json({ limit: '10mb' }));
// Rate limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: 'Too many requests from this IP'
});
app.use('/api/', limiter);
// Authentication middleware for different security levels
app.use('/api/public', (req, res, next) => next()); // No auth required
app.use('/api/protected', authMiddleware('signature')); // Standard auth
app.use('/api/admin', authMiddleware('hash')); // High security
// Health check
app.get('/health', (req, res) => {
res.json({
status: 'healthy',
timestamp: new Date().toISOString(),
environment: process.env.NODE_ENV
});
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`🚀 Production server running on port ${PORT}`);
});3. Client Integration Example
const { API_CALL } = require('auth-fingerprint/api');
// Authenticated API call with built-in fingerprint authentication
const response = await API_CALL({
method: 'POST',
url: '/secure/data',
baseURL: 'https://api.example.com',
body: { userId: 123 },
auth: { enabled: true, method: 'signature' }
});
console.log('Response:', response.response);📋 Complete API Reference
API_CALL Configuration
const response = await API_CALL({
method: 'GET|POST|PUT|DELETE|PATCH', // HTTP method
url: '/endpoint', // API endpoint
baseURL: 'https://api.example.com', // Base URL
body: { data: 'value' }, // Request body
headers: { // Custom headers
'Authorization': 'Bearer token',
'X-CSRF-Token': 'csrf-token'
},
params: { page: 1, limit: 10 }, // URL parameters
auth: { // Authentication config
enabled: true, // Enable fingerprint auth
method: 'signature', // 'hash' or 'signature'
secret: 'custom-secret', // Custom secret key
fingerprint: { ip: '1.2.3.4' } // Custom fingerprint
}
});🪙 Blockchain Operations (NEW)
ERC-20 Token Operations
Get ERC-20 Token Balance
const { getERC20Balance, formatTokenBalance } = require('auth-fingerprint/erc_20');
const rpcUrl = "https://eth.llamarpc.com";
const tokenAddress = "0x6982508145454Ce325dDbE47a25d4ec3d2311933"; // PEPE token
const walletAddress = "0x742d35Cc6634C0532925a3b8D0C9e3e0C0e0e0e0";
// Get raw balance
const balance = await getERC20Balance(rpcUrl, tokenAddress, walletAddress);
console.log("Raw balance:", balance);
// Format balance to human-readable format
const formattedBalance = formatTokenBalance(balance, 18); // 18 decimals
console.log("Formatted balance:", formattedBalance, "tokens");Send ERC-20 Tokens
const { sendErc20, toBigInt } = require('auth-fingerprint/erc_20');
const rpcUrl = "https://eth-sepolia.api.onfinality.io/public";
const privateKey = "your-private-key";
const tokenAddress = "0xB9081a3d73A977F427d077953312762b9A10774B";
const recipient = "0x5875ed358C4a3Cd38eBf3f086454dbAC657aaDbA";
const amount = "1.5"; // 1.5 tokens
const decimals = 18;
// Send ERC-20 tokens
await sendErc20(rpcUrl, privateKey, tokenAddress, recipient, amount, decimals);
// Convert amount to BigInt manually
const amountInWei = toBigInt(amount, decimals);
console.log("Amount in smallest unit:", amountInWei.toString());Get Deposit History
const { getDepositHistory } = require('auth-fingerprint/erc_20');
const tokenAddress = "0x6982508145454Ce325dDbE47a25d4ec3d2311933";
const walletAddress = "0x742d35Cc6634C0532925a3b8D0C9e3e0C0e0e0e0";
const rpcUrl = "https://eth.llamarpc.com";
// Get deposits from last 24 hours
const deposits = await getDepositHistory(tokenAddress, walletAddress, rpcUrl);
console.log("Recent deposits:");
deposits.forEach(deposit => {
console.log({
from: deposit.from,
amount: formatTokenBalance(deposit.amount, 18),
timestamp: deposit.timestamp,
txHash: deposit.txHash
});
});Native ETH Operations
Send Native ETH
const { sendNativeToken } = require('auth-fingerprint/lib');
const rpcUrl = "https://eth-sepolia.api.onfinality.io/public";
const privateKey = "your-private-key";
const recipient = "0x5875ed358C4a3Cd38eBf3f086454dbAC657aaDbA";
const amount = "0.001"; // 0.001 ETH
// Send ETH
const result = await sendNativeToken(rpcUrl, privateKey, recipient, amount);
if (result.success) {
console.log("Transaction sent! Hash:", result.hash);
console.log("Confirmations:", result.confirmations);
} else {
console.error("Transaction failed:", result.error);
}Get Native ETH Balance
const { getNativeBalance, formatNativeBalance } = require('auth-fingerprint/lib');
const rpcUrl = "https://eth.llamarpc.com";
const walletAddress = "0x742d35Cc6634C0532925a3b8D0C9e3e0C0e0e0e0";
// Get balance in wei
const balanceWei = await getNativeBalance(rpcUrl, walletAddress);
console.log("Balance in wei:", balanceWei);
// Format to ETH
const balanceEth = formatNativeBalance(balanceWei);
console.log("Balance in ETH:", balanceEth);Blockchain Utilities
Transaction Information
const {
getTransactionByHash,
getTransactionReceipt,
getBlockNumber
} = require('auth-fingerprint/lib');
const rpcUrl = "https://eth.llamarpc.com";
const txHash = "0x1234567890abcdef1234567890abcdef12345678";
// Get transaction details
const tx = await getTransactionByHash(rpcUrl, txHash);
console.log("Transaction details:", {
from: tx.from,
to: tx.to,
value: tx.value,
gasPrice: tx.gasPrice,
blockNumber: tx.blockNumber
});
// Get transaction receipt
const receipt = await getTransactionReceipt(rpcUrl, txHash);
console.log("Transaction receipt:", {
status: receipt.status,
gasUsed: receipt.gasUsed,
logs: receipt.logs.length
});
// Get current block number
const blockNumber = await getBlockNumber(rpcUrl);
console.log("Current block:", parseInt(blockNumber, 16));Complete DeFi Wallet Example
const {
sendErc20,
getERC20Balance,
formatTokenBalance,
getDepositHistory
} = require('auth-fingerprint/erc_20');
const {
sendNativeToken,
getNativeBalance,
formatNativeBalance
} = require('auth-fingerprint/lib');
class DeFiWallet {
constructor(rpcUrl, privateKey) {
this.rpcUrl = rpcUrl;
this.privateKey = privateKey;
this.address = "0x742d35Cc6634C0532925a3b8D0C9e3e0C0e0e0e0"; // Derive from private key
}
// Get portfolio overview
async getPortfolio() {
try {
// Get ETH balance
const ethBalance = await getNativeBalance(this.rpcUrl, this.address);
const ethFormatted = formatNativeBalance(ethBalance);
// Get USDC balance (example token)
const usdcAddress = "0xA0b86a33E6441c8C06DD2c5685E9B0B5B8e0e0e0";
const usdcBalance = await getERC20Balance(this.rpcUrl, usdcAddress, this.address);
const usdcFormatted = formatTokenBalance(usdcBalance, 6); // USDC has 6 decimals
return {
eth: { balance: ethFormatted, symbol: 'ETH' },
usdc: { balance: usdcFormatted, symbol: 'USDC' },
address: this.address
};
} catch (error) {
console.error('Portfolio fetch failed:', error.message);
return null;
}
}
// Send tokens with validation
async sendToken(tokenAddress, recipient, amount, decimals = 18) {
try {
// Validate token balance
const balance = await getERC20Balance(this.rpcUrl, tokenAddress, this.address);
const formattedBalance = formatTokenBalance(balance, decimals);
if (parseFloat(formattedBalance) < parseFloat(amount)) {
throw new Error(`Insufficient balance. Have: ${formattedBalance}, Need: ${amount}`);
}
// Validate ETH for gas
const ethBalance = await getNativeBalance(this.rpcUrl, this.address);
const ethFormatted = formatNativeBalance(ethBalance);
if (parseFloat(ethFormatted) < 0.001) {
throw new Error(`Insufficient ETH for gas. Have: ${ethFormatted} ETH`);
}
// Execute transfer
console.log(`🚀 Sending ${amount} tokens to ${recipient}...`);
const result = await sendErc20(
this.rpcUrl,
this.privateKey,
tokenAddress,
recipient,
amount,
decimals
);
console.log('✅ Transfer successful!');
return result;
} catch (error) {
console.error('❌ Transfer failed:', error.message);
throw error;
}
}
// Get transaction history
async getTransactionHistory(tokenAddress) {
try {
const deposits = await getDepositHistory(tokenAddress, this.address, this.rpcUrl);
return deposits.map(deposit => ({
type: 'deposit',
from: deposit.from,
amount: formatTokenBalance(deposit.amount, 18),
timestamp: new Date(deposit.timestamp * 1000).toISOString(),
txHash: deposit.txHash
}));
} catch (error) {
console.error('History fetch failed:', error.message);
return [];
}
}
}
// Usage example
async function demoWallet() {
const wallet = new DeFiWallet(
"https://eth-sepolia.api.onfinality.io/public",
"your-private-key"
);
// Get portfolio
const portfolio = await wallet.getPortfolio();
console.log('💼 Portfolio:', portfolio);
// Send USDC tokens
try {
await wallet.sendToken(
"0xA0b86a33E6441c8C06DD2c5685E9B0B5B8e0e0e0", // USDC
"0x5875ed358C4a3Cd38eBf3f086454dbAC657aaDbA",
"10.50",
6 // USDC decimals
);
} catch (error) {
console.error('Transfer error:', error.message);
}
// Get transaction history
const history = await wallet.getTransactionHistory(
"0xA0b86a33E6441c8C06DD2c5685E9B0B5B8e0e0e0"
);
console.log('📊 Recent transactions:', history);
}
// Run the demo
demoWallet();4. Monitoring & Logging
const winston = require('winston');
// Security event logging
const securityLogger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new winston.transports.File({ filename: 'security.log' }),
new winston.transports.Console()
]
});
// Log authentication events
function logAuthEvent(event, req, success = true) {
const fingerprint = getDeviceFingerprint(req);
securityLogger.info({
event,
success,
ip: fingerprint.ip,
userAgent: fingerprint.userAgent,
timestamp: new Date().toISOString(),
endpoint: req.path
});
}
// Usage in middleware
app.use('/api/protected', (req, res, next) => {
const authResult = authMiddleware('signature')(req, res, () => {});
logAuthEvent('authentication_attempt', req, !!req.authData);
next();
});🔧 Troubleshooting
Common Issues
1. "Authentication failed: expired" Error
// Increase tolerance for network delays
const verification = verifySignature(payload, secret, 120000); // 2 minutes2. "Device fingerprint mismatch" Error
// Handle dynamic IPs and user agent changes
function flexibleFingerprint(req) {
const base = getDeviceFingerprint(req);
return {
// Use more stable identifiers
userAgent: base.userAgent.split(' ')[0], // Just browser name
acceptLanguage: base.acceptLanguage,
timezone: req.headers['x-timezone'] || 'UTC'
};
}3. High Memory Usage with Large Payloads
// Limit payload size and use streaming
app.use(express.json({ limit: '1mb' }));
// For large data, use hash-based verification instead of signatures
const result = hashFingerprint(smallFingerprint, secret);📚 Additional Resources
- 📖 Complete API Documentation
- 🎥 Video Tutorial Series
- 💬 Community Discord
- 🐛 Report Issues
- 📧 Security Contact
📜 License
ISC © 2025 Md Rijon Hossain Jibon YT

