Many legacy applications or lightweight clients lack support for HTTP Basic Authentication, while modern APIs frequently require it. Here's a solution using Node.js that creates a middleware proxy to inject credentials transparently.
We'll build this using Node.js with Express and http-proxy-middleware for several advantages:
- Cross-platform support (Windows/Linux/macOS)
- Minimal dependencies
- Easy credential configuration
First install required packages:
npm install express http-proxy-middleware dotenv
Here's the complete proxy server implementation (save as proxy-auth.js
):
require('dotenv').config(); const express = require('express'); const { createProxyMiddleware } = require('http-proxy-middleware'); const app = express(); const PORT = process.env.PORT || 3000; const TARGET = process.env.TARGET_URL; const AUTH = Buffer.from(${process.env.AUTH_USER}:${process.env.AUTH_PASS}).toString('base64'); app.use('/', createProxyMiddleware({ target: TARGET, changeOrigin: true, onProxyReq: (proxyReq) => { proxyReq.setHeader('Authorization', Basic ${AUTH}); }, logger: console })); app.listen(PORT, () => { console.log(Auth proxy running on http://localhost:${PORT}); console.log(Proxying requests to ${TARGET} with Basic Auth); });
Create a .env
file:
TARGET_URL=https://api.secured-service.com AUTH_USER=service_account AUTH_PASS=complex_password_123 PORT=8080
For non-Node.js environments, consider these options:
Nginx Reverse Proxy
server { listen 80; location / { proxy_pass https://target-service.com; proxy_set_header Authorization "Basic [base64-encoded-credentials]"; } }
Python with Requests
from flask import Flask import requests app = Flask(__name__) AUTH = ('username', 'password') @app.route('/<path:subpath>') def proxy(subpath): resp = requests.get(f'https://remote/{subpath}', auth=AUTH) return resp.content, resp.status_code
- Never hardcode credentials in source files
- Use environment variables or secret management systems
- Consider adding IP whitelisting for the proxy endpoint
- Enable HTTPS for the proxy connection
Verify with curl:
curl http://localhost:8080/api/resource
Should return the same response as:
curl -u user:pass https://api.secured-service.com/api/resource
Many legacy applications lack built-in HTTP authentication support, while modern APIs increasingly require Basic Auth. This creates integration challenges when you need to connect auth-less clients to protected resources. A lightweight proxy solution can bridge this gap by injecting credentials transparently.
We'll implement a reverse proxy that:
- Accepts unauthenticated requests from your application
- Adds Basic Authentication headers
- Forwards requests to the target server
- Returns responses unchanged to the client
Here's a complete proxy implementation using Python Flask:
from flask import Flask, request, abort
import requests
from base64 import b64encode
app = Flask(__name__)
PROXY_USER = 'your_username'
PROXY_PASS = 'your_password'
TARGET_SERVER = 'https://protected-api.example.com'
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
def proxy(path):
# Construct target URL
target_url = f"{TARGET_SERVER}/{path}"
# Prepare auth header
credentials = f"{PROXY_USER}:{PROXY_PASS}"
encoded_credentials = b64encode(credentials.encode()).decode()
headers = {
"Authorization": f"Basic {encoded_credentials}",
**dict(request.headers)
}
# Forward request
try:
resp = requests.request(
method=request.method,
url=target_url,
headers=headers,
data=request.get_data(),
cookies=request.cookies,
allow_redirects=False
)
except requests.exceptions.RequestException as e:
abort(502, str(e))
# Return response
return (resp.content, resp.status_code, resp.headers.items())
if __name__ == '__main__':
app.run(port=8080)
For production environments, you can configure Nginx as a proxy:
server {
listen 80;
server_name proxy.example.com;
location / {
proxy_pass https://protected-api.example.com;
proxy_set_header Authorization "Basic $(echo -n 'username:password' | base64)";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Verify the proxy works by making direct HTTP requests:
curl http://localhost:8080/api/resource
Compare the response with direct authenticated access:
curl -u username:password https://protected-api.example.com/api/resource
- Always use HTTPS for both client-proxy and proxy-server communication
- Store credentials securely (environment variables or secret manager)
- Implement rate limiting to prevent abuse
- Consider adding IP whitelisting if applicable
For high-traffic scenarios:
- Enable connection pooling in your proxy
- Implement caching for GET requests
- Consider using a compiled language (Go, Rust) for the proxy
- Add health checks for the target server