- Home
- HTTP Headers
- Proxy-Authorization Header
Header
Proxy-Authorization Header
Learn how Proxy-Authorization provides credentials to access resources through a proxy server. Understand proxy authentication schemes and security.
What is Proxy-Authorization?
TL;DR: Provides authentication credentials to access resources through a proxy server. Sent in response to 407 Proxy Authentication Required challenges.
The Proxy-Authorization header is used to authenticate with a proxy server that requires credentials before forwarding requests to the destination server. It’s like showing your ID to a security guard (the proxy) before they let you through to enter a building (the destination server).
This header is similar to the Authorization header, but it’s specifically for authenticating with proxy servers, not the destination server.
How Proxy-Authorization Works
Request without credentials (first attempt):
GET https://api.example.com/data HTTP/1.1
Host: api.example.com
```text
**Proxy responds with authentication challenge:**
```http
HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: Basic realm="Corporate Proxy"
Content-Length: 0
Request with credentials:
GET https://api.example.com/data HTTP/1.1
Host: api.example.com
Proxy-Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
```text
**Proxy forwards request to destination:**
```http
GET /data HTTP/1.1
Host: api.example.com
HTTP/1.1 200 OK
Content-Type: application/json
{"data": "value"}
Syntax
Proxy-Authorization: <type> <credentials>
```text
The format varies by authentication scheme.
### Basic Authentication
```http
Proxy-Authorization: Basic <base64-encoded-credentials>
Credentials format: username:password encoded in Base64
# username: user, password: pass
# "user:pass" → base64 → "dXNlcjpwYXNz"
Proxy-Authorization: Basic dXNlcjpwYXNz
```text
### Bearer Token
```http
Proxy-Authorization: Bearer <token>
Proxy-Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```text
### Digest Authentication
```http
Proxy-Authorization: Digest username="user", realm="proxy", nonce="...", uri="/", response="..."
Common Examples
Basic Proxy Authentication
Request:
GET https://api.example.com/users HTTP/1.1
Host: api.example.com
Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==
```text
### Corporate Proxy with Token
```http
GET https://api.example.com/data HTTP/1.1
Host: api.example.com
Proxy-Authorization: Bearer proxy-token-abc123xyz
Multiple Authentications (Proxy and Server)
GET https://api.example.com/protected HTTP/1.1
Host: api.example.com
Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
```javascript
The proxy uses `Proxy-Authorization`, the destination server uses `Authorization`.
## Real-World Scenarios
### Corporate Network Access
**JavaScript fetch through corporate proxy:**
```javascript
// Browser automatically handles proxy authentication if configured
// Or manually for Node.js
const https = require('https')
const HttpsProxyAgent = require('https-proxy-agent')
const proxyUrl = 'http://username:password@proxy.company.com:8080'
const agent = new HttpsProxyAgent(proxyUrl)
fetch('https://api.example.com/data', {
agent: agent
})
.then((response) => response.json())
.then((data) => console.log(data))
Node.js with Proxy Authentication
const axios = require('axios')
const HttpsProxyAgent = require('https-proxy-agent')
const proxyAgent = new HttpsProxyAgent({
host: 'proxy.company.com',
port: 8080,
auth: 'username:password'
})
axios
.get('https://api.example.com/data', {
httpsAgent: proxyAgent,
proxy: false // Don't use axios proxy, use agent instead
})
.then((response) => console.log(response.data))
```javascript
### Environment-Based Proxy Configuration
```javascript
// Read proxy config from environment
const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY
if (proxyUrl) {
const agent = new HttpsProxyAgent(proxyUrl)
// Use with fetch
fetch('https://api.example.com/data', { agent })
}
// Example environment variables:
// HTTPS_PROXY=http://user:pass@proxy.company.com:8080
// HTTP_PROXY=http://user:pass@proxy.company.com:8080
// NO_PROXY=localhost,127.0.0.1,.local
Authenticated Proxy with Certificate Validation
const https = require('https')
const HttpsProxyAgent = require('https-proxy-agent')
const fs = require('fs')
const agent = new HttpsProxyAgent({
host: 'proxy.company.com',
port: 8080,
auth: 'username:password',
ca: fs.readFileSync('proxy-ca-cert.pem'), // Corporate CA
rejectUnauthorized: true
})
https.get('https://api.example.com/data', { agent }, (res) => {
console.log('Status:', res.statusCode)
})
```javascript
## Encoding Credentials
### Basic Authentication Encoding
```javascript
// Encode username:password to Base64
function encodeBasicAuth(username, password) {
const credentials = `${username}:${password}`
return Buffer.from(credentials).toString('base64')
}
const encoded = encodeBasicAuth('proxyuser', 'proxypass')
console.log(`Proxy-Authorization: Basic ${encoded}`)
// Output: Proxy-Authorization: Basic cHJveHl1c2VyOnByb3h5cGFzcw==
Command Line
# Encode credentials
echo -n "username:password" | base64
# Output: dXNlcm5hbWU6cGFzc3dvcmQ=
# Use with curl
curl -x http://proxy.company.com:8080 \
-H "Proxy-Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" \
https://api.example.com/data
# Or let curl encode it
curl -x http://username:password@proxy.company.com:8080 \
https://api.example.com/data
```javascript
## Security Considerations
### 1. Use HTTPS for Proxy Connection
```javascript
// ❌ Credentials sent in clear text over HTTP proxy
const agent = new HttpsProxyAgent('http://user:pass@proxy.com:8080')
// ✅ Use HTTPS proxy or tunnel
const agent = new HttpsProxyAgent('https://user:pass@proxy.com:8443')
2. Don’t Log Credentials
// ❌ Logs contain credentials
console.log('Making request with headers:', {
'Proxy-Authorization': 'Basic dXNlcjpwYXNz'
})
// ✅ Redact sensitive headers
function sanitizeHeaders(headers) {
const sanitized = { ...headers }
if (sanitized['Proxy-Authorization']) {
sanitized['Proxy-Authorization'] = '[REDACTED]'
}
return sanitized
}
console.log('Making request with headers:', sanitizeHeaders(headers))
```javascript
### 3. Store Credentials Securely
```javascript
// ❌ Hardcoded credentials
const proxyAuth = 'Basic dXNlcjpwYXNz'
// ✅ Use environment variables
const proxyAuth = process.env.PROXY_AUTH
// ✅ Or use secrets management
const proxyAuth = await getSecretFromVault('proxy-credentials')
4. Rotate Credentials Regularly
// ✅ Support credential rotation
async function getProxyAuth() {
// Fetch fresh credentials from secrets manager
const credentials = await secretsManager.getSecret('proxy-creds')
return `Basic ${Buffer.from(credentials).toString('base64')}`
}
// Use in request
const proxyAuth = await getProxyAuth()
```javascript
## Best Practices
### 1. Handle 407 Responses
```javascript
async function fetchWithProxyAuth(url, credentials) {
let response = await fetch(url)
if (response.status === 407) {
// Proxy authentication required
const auth = Buffer.from(credentials).toString('base64')
response = await fetch(url, {
headers: {
'Proxy-Authorization': `Basic ${auth}`
}
})
}
return response
}
2. Support Multiple Authentication Schemes
function createProxyAuthHeader(scheme, credentials) {
switch (scheme) {
case 'Basic':
return `Basic ${Buffer.from(credentials).toString('base64')}`
case 'Bearer':
return `Bearer ${credentials}`
case 'Digest':
// Implement digest auth
return calculateDigestAuth(credentials)
default:
throw new Error(`Unsupported scheme: ${scheme}`)
}
}
```javascript
### 3. Configure Proxy Bypass
```javascript
const NO_PROXY = process.env.NO_PROXY || ''
const noProxyList = NO_PROXY.split(',').map((h) => h.trim())
function shouldUseProxy(url) {
const hostname = new URL(url).hostname
// Check if hostname is in no-proxy list
return !noProxyList.some((pattern) => {
if (pattern.startsWith('.')) {
return hostname.endsWith(pattern)
}
return hostname === pattern
})
}
// Use proxy only if needed
if (shouldUseProxy(targetUrl)) {
options.agent = proxyAgent
}
4. Handle Proxy Errors
async function fetchThroughProxy(url, proxyConfig) {
const agent = new HttpsProxyAgent(proxyConfig)
try {
const response = await fetch(url, { agent })
if (response.status === 407) {
throw new Error('Proxy authentication failed')
}
if (response.status === 502) {
throw new Error('Proxy cannot reach destination')
}
if (response.status === 504) {
throw new Error('Proxy timeout')
}
return response
} catch (error) {
if (error.code === 'ECONNREFUSED') {
throw new Error('Cannot connect to proxy')
}
throw error
}
}
```javascript
## Common Patterns
### Automatic Proxy Detection
```javascript
function getProxyConfig() {
// Check environment variables
const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy
const httpProxy = process.env.HTTP_PROXY || process.env.http_proxy
if (httpsProxy) {
const url = new URL(httpsProxy)
return {
host: url.hostname,
port: url.port,
auth: url.username && url.password ? `${url.username}:${url.password}` : null
}
}
return null
}
// Use it
const proxyConfig = getProxyConfig()
if (proxyConfig) {
const agent = new HttpsProxyAgent(proxyConfig)
// Use agent in requests
}
Proxy Middleware (Express)
const { createProxyMiddleware } = require('http-proxy-middleware')
app.use(
'/api',
createProxyMiddleware({
target: 'https://api.example.com',
changeOrigin: true,
onProxyReq: (proxyReq, req, res) => {
// Add proxy authentication
const proxyAuth = process.env.PROXY_AUTH
if (proxyAuth) {
proxyReq.setHeader('Proxy-Authorization', `Basic ${proxyAuth}`)
}
}
})
)
```text
## Testing
### Test with curl
```bash
# Test proxy authentication
curl -x http://proxy.company.com:8080 \
--proxy-user username:password \
https://api.example.com/data
# Or with explicit header
curl -x http://proxy.company.com:8080 \
-H "Proxy-Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" \
https://api.example.com/data
# Verbose output to see proxy negotiation
curl -x http://proxy.company.com:8080 \
--proxy-user username:password \
-v https://api.example.com/data
Test Proxy Connection
async function testProxyConnection(proxyUrl) {
const agent = new HttpsProxyAgent(proxyUrl)
try {
const response = await fetch('https://api.ipify.org?format=json', {
agent: agent
})
if (response.ok) {
const data = await response.json()
console.log('Proxy working! External IP:', data.ip)
return true
}
} catch (error) {
console.error('Proxy test failed:', error.message)
return false
}
}
// Test
testProxyConnection('http://user:pass@proxy.company.com:8080')
Difference from Authorization Header
| Feature | Proxy-Authorization | Authorization |
|---|---|---|
| Purpose | Authenticate with proxy | Authenticate with server |
| Used by | Proxy server | Destination server |
| Stripped by | Proxy (not forwarded) | Kept through chain |
| Status code | 407 (Proxy Auth Required) | 401 (Unauthorized) |
| Challenge header | Proxy-Authenticate | WWW-Authenticate |
Related Headers
- Authorization - Server authentication
- Proxy-Authenticate - Proxy auth challenge
- WWW-Authenticate - Server auth challenge
- Via - Proxy chain information
Frequently Asked Questions
What is Proxy-Authorization?
Proxy-Authorization sends credentials to authenticate with a proxy server. It is the response to a 407 Proxy Authentication Required challenge.
How is Proxy-Authorization different from Authorization?
Authorization authenticates with the origin server. Proxy-Authorization authenticates with an intermediate proxy. Both can be present in the same request.
What format does Proxy-Authorization use?
Same format as Authorization: scheme followed by credentials. For Basic: "Proxy-Authorization: Basic base64(user:pass)". For other schemes, follow their specification.
Is Proxy-Authorization secure?
Basic scheme sends credentials in base64 (easily decoded). Always use HTTPS between client and proxy, or use more secure schemes like Digest or negotiate.