Although it can be difficult to secure an API without standard user authentication, there are a number of easy steps you can take to guard against exploitation and unwanted access.
1. IP Whitelisting (IP Restriction)
Only allow requests from specified IP addresses.
- Using NGINX (as a reverse proxy):
 
http {
  ...
  server {
    ...
    location /api {
      # Restrict API access to these IPs
      allow 192.168.1.100;
      allow 2001:0db8:85a3:0000:0000:8a2e:0370:7334;
      deny all; # Deny all other IP addresses
    }
  }
}
- Using AWS API Gateway: Configure "Resource Policy" to restrict source IP addresses.
 
2. Rate Limiting
Limit the number of requests from an IP address within a time frame.
- Using Node.js with Express and rate-limit middleware:
 
const rateLimit = require("express-rate-limit");
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes)
  standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
  legacyHeaders: false, // Disable the `X-RateLimit-*` headers
});
// Apply to all API endpoints
app.use("/api/", limiter);
- Using Cloudflare: Enable the "Rate Limiting" rule in the dashboard.
 
3. API Tokens (without User Auth)
Require a static, secret token to be passed with each request.
from flask import Flask, request, abort
app = Flask(__name__)
API_TOKEN = "your_secret_static_token_here"
@app.before_request
def require_api_token():
  if request.headers.get('X-API-TOKEN') != API_TOKEN:
    abort(401)
@app.route('/api/endpoint')
def protected_endpoint():
  return "Access granted."
4. User Agent Restriction
Restrict access based on the User-Agent header.
SetEnvIf User-Agent "^YourApprovedBotName" let_in
Order Deny,Allow
Deny from all
Allow from env=let_in
5. Content Security Policy (CSP) and CORS
Define which sources of content are allowed to interact with your API.
- Implementing CORS with Python and Flask to only allow specific origins:
 
from flask import Flask
from flask_cors import CORS, cross_origin
app = Flask(__name__)
cors = CORS(app, resources={r"/api/*": {"origins": "https://example.com"}})
- CSP with NGINX for API responses:
 
http {
  ...
  server {
    ...
    location /api {
      # Other configurations
      add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://example.com;";
    }
  }
}
Related Questions Compromised API token issue
Encrypt SD card without device