Node.js › Authentication & Authorization

How would you implement API key authentication for a Node.js service consumed by other backend services, and what are its security limitations?

Advanced

Answer

API key authentication issues each consuming service a unique, typically long random string sent via a header on every request, checked server-side against a stored (ideally hashed) list of valid keys -- simple to implement and suitable for service-to-service communication, but limited because API keys typically don't expire on their own, carry no fine-grained claims like a JWT does, and if leaked (in logs, source control, or client-side code) remain valid until manually revoked, making key rotation and secure storage critical.
app.use((req, res, next) => {
  const apiKey = req.headers['x-api-key'];
  const hashedKey = crypto.createHash('sha256').update(apiKey || '').digest('hex');
  const client = apiKeyStore.findByHash(hashedKey);
  if (!client) return res.status(401).json({ error: 'Invalid API key' });
  req.client = client;
  next();
});
Real-world example A weather-data API issues each paying customer a unique API key, storing only its SHA-256 hash in the database (never the raw key, mirroring password-storage best practice), and provides a self-service dashboard for customers to rotate their key immediately if they suspect it has leaked.

Common follow-ups: Why is storing a hash of the API key rather than the raw key itself considered best practice, similar to passwords?;How would you add rate limiting scoped per API key rather than per IP address?