Common Request Headers
Request Headers
Request headers are sent by the client with every request to provide metadata.
| Header | Purpose | Example |
|---|---|---|
| Host | Target domain | magento-store.com |
| User-Agent | Client software info | Mozilla/5.0 (Windows...) |
| Accept | Preferred response format | text/html, application/json |
| Accept-Language | Preferred language | en-US, en;q=0.9 |
| Accept-Encoding | Compression support | gzip, deflate, br |
| Content-Type | Body format | application/json |
| Authorization | Authentication credentials | Bearer eyJhbGciOi... |
| Cookie | Session cookies | PHPSESSID=abc123 |
| Cache-Control | Caching directives | no-cache |
| If-None-Match | ETag for cache validation | "abc123" |
| If-Modified-Since | Last modified date | Mon, 01 Jan 2026... |
PHP: Reading Request Headers
<?php
// Method 1: $_SERVER superglobal
$accept = $_SERVER['HTTP_ACCEPT'];
$userAgent = $_SERVER['HTTP_USER_AGENT'];
$authorization = $_SERVER['HTTP_AUTHORIZATION'] ?? null;
// Method 2: getallheaders() function
$headers = getallheaders();
$contentType = $headers['Content-Type'] ?? null;
$accept = $headers['Accept'] ?? null;
// Method 3: Get specific header with custom name
function getHeader(string $name): ?string
{
$headers = getallheaders();
// Headers can be different cases
foreach ($headers as $key => $value) {
if (strtolower($key) === strtolower($name)) {
return $value;
}
}
return null;
}
// Parse Accept header to check supported formats
$accept = $_SERVER['HTTP_ACCEPT'] ?? '';
$wantsJson = strpos($accept, 'application/json') !== false;
$wantsHtml = strpos($accept, 'text/html') !== false;
if ($wantsJson) {
header('Content-Type: application/json');
echo json_encode($data);
} elseif ($wantsHtml) {
header('Content-Type: text/html');
echo renderTemplate($data);
}
Authorization Header Patterns
<?php
// Bearer token authentication (Magento REST API style)
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if (preg_match('/^Bearer\s+(.+)$/i', $authHeader, $matches)) {
$token = $matches[1];
$user = validateBearerToken($token);
if (!$user) {
http_response_code(401);
echo json_encode(['error' => 'Invalid token']);
exit;
}
} else {
http_response_code(401);
header('WWW-Authenticate: Bearer realm="api"');
echo json_encode(['error' => 'Authorization header required']);
exit;
}
// Basic authentication (admin panel style)
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if (preg_match('/^Basic\s+(.+)$/i', $authHeader, $matches)) {
$decoded = base64_decode($matches[1]);
[$username, $password] = explode(':', $decoded, 2);
$user = authenticateUser($username, $password);
if (!$user) {
http_response_code(401);
header('WWW-Authenticate: Basic realm="Admin"');
exit;
}
}
Response Headers: Content-Type, Cache-Control, Security
Response Headers
Response headers are sent by the server to control how the client processes the response.
| Header | Purpose | Example |
|---|---|---|
| Content-Type | Response body format | application/json; charset=UTF-8 |
| Content-Length | Body size in bytes | 45213 |
| Cache-Control | Caching behavior | max-age=3600, private |
| Expires | Expiration date | Mon, 01 Jan 2027 00:00:00 GMT |
| ETag | Resource version hash | "abc123" |
| Location | Redirect URL | https://magento-store.com/ |
| Set-Cookie | Set a cookie | session=abc123; Path=/ |
| X-Content-Type-Options | Prevent MIME sniffing | nosniff |
| X-Frame-Options | Prevent clickjacking | SAMEORIGIN |
| X-XSS-Protection | XSS protection | 1; mode=block |
| Strict-Transport-Security | Force HTTPS | max-age=31536000 |
PHP: Setting Response Headers
<?php
// Basic header setting
header('Content-Type: application/json; charset=UTF-8');
header('X-Custom-Header: SomeValue');
// Remove a header
header_remove('X-Powered-By');
// Set status code with headers
header('HTTP/1.1 200 OK');
http_response_code(200); // Alternative
// Content-Type for different formats
header('Content-Type: text/html; charset=UTF-8');
header('Content-Type: application/json; charset=UTF-8');
header('Content-Type: text/xml; charset=UTF-8');
header('Content-Type: image/png');
// Send file download
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="export.csv"');
header('Content-Length: ' . filesize($filePath));
readfile($filePath);
Caching Headers
<?php
// No caching - dynamic content
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
// Cache for 1 hour
header('Cache-Control: public, max-age=3600');
header('Last-Modified: ' . date('r', $lastModified));
// Cache for 1 week
header('Cache-Control: public, max-age=604800');
header('ETag: "' . md5_file($filePath) . '"');
// Private cache (user-specific, like cart page)
header('Cache-Control: private, max-age=300');
// Validation with ETag
$etag = md5_file($filePath);
header('ETag: "' . $etag . '"');
if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] === '"' . $etag . '"') {
http_response_code(304);
exit;
}
Security Headers
<?php
// Security headers - should be on every response
header('X-Content-Type-Options: nosniff'); // Prevent MIME type sniffing
header('X-Frame-Options: SAMEORIGIN'); // Prevent clickjacking
header('X-XSS-Protection: 1; mode=block'); // Enable XSS filter
header('Referrer-Policy: strict-origin-when-cross-origin');
header('Content-Security-Policy: default-src \'self\'; script-src \'self\' \'unsafe-inline\'');
header('Strict-Transport-Security: max-age=31536000; includeSubDomains'); // HSTS
// Remove server identification headers
header_remove('X-Powered-By');
header_remove('Server');
Magento Security Headers
Magento applies these headers through Magento\Framework\Response\HeaderManager:
X-Content-Type-Options: nosniffX-Frame-Options: SAMEORIGINX-XSS-Protection: 1; mode=blockX-Download-Options: noopenX-Permitted-Cross-Domain-Policies: none
CORS Headers for Cross-Origin Requests
Understanding CORS
CORS (Cross-Origin Resource Sharing) controls how resources can be requested from a different domain.
Same-Origin Policy: Browsers block requests to a different domain by default.
CORS Headers: Tell the browser which domains are allowed to access the resource.
CORS Headers
| Header | Purpose | Example |
|---|---|---|
| Access-Control-Allow-Origin | Allowed origins | https://magento-store.com |
| Access-Control-Allow-Methods | Allowed HTTP methods | GET, POST, PUT, DELETE |
| Access-Control-Allow-Headers | Allowed request headers | Content-Type, Authorization |
| Access-Control-Allow-Credentials | Allow cookies/auth | true |
| Access-Control-Max-Age | Cache preflight results | 86400 (24 hours) |
| Access-Control-Expose-Headers | Headers the client can read | X-Request-Id |
PHP CORS Implementation
<?php
// CORS middleware - add to every API response
function setCorsHeaders(): void
{
// Get the requesting origin
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
// Define allowed origins
$allowedOrigins = [
'https://magento-store.com',
'https://www.magento-store.com',
'https://admin.magento-store.com'
];
// Check if origin is allowed
if (in_array($origin, $allowedOrigins)) {
header('Access-Control-Allow-Origin: ' . $origin);
}
// Allow credentials (cookies, auth headers)
header('Access-Control-Allow-Credentials: true');
// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, X-Custom-Header');
header('Access-Control-Max-Age: 86400'); // Cache for 24 hours
http_response_code(204);
exit;
}
}
// Call this at the start of every API request
setCorsHeaders();
// Now handle the actual request
$product = getProductById($_GET['id']);
header('Content-Type: application/json');
echo json_encode($product);
Preflight vs Simple Requests
Simple requests (no preflight needed):
- Method: GET, HEAD, POST
- Headers: Accept, Content-Language, Content-Type (with limited values)
- Content-Type: text/plain, multipart/form-data, application/x-www-form-urlencoded
Preflight requests (browser sends OPTIONS first):
- Method: PUT, DELETE, PATCH
- Headers: Authorization, Content-Type: application/json
- Any custom headers
Magento CORS Configuration
<!-- app/code/Vendor/Module/etc/frontend/di.xml -->
<config>
<type name="Magento\Framework\App\Response\CORS">
<arguments>
<argument name="allowedOrigins" xsi:type="array">
<item name="frontend" xsi:type="string">https://magento-store.com</item>
<item name="admin" xsi:type="string">https://admin.magento-store.com</item>
</argument>
</arguments>
</type>
</config>
Common CORS Errors and Fixes
| Error | Cause | Fix |
|---|---|---|
| Missing Access-Control-Allow-Origin | No CORS headers sent | Add CORS header for the origin |
| Origin not allowed | Origin not in allowed list | Add origin to allowed list |
| Credentials not supported | Allow-Credentials not true | Set Access-Control-Allow-Credentials: true |
| Method not allowed | OPTIONS preflight failed | Include method in Access-Control-Allow-Methods |
| Header not allowed | Request header not in Allow-Headers | Add header to Access-Control-Allow-Headers |
Key Takeaway
CORS is a browser security feature that controls cross-origin requests. For Magento REST APIs consumed by frontend JavaScript or mobile apps, proper CORS configuration is essential.
Quiz
1. How do you read a request header in PHP?
2. What does the Cache-Control: no-cache header mean?
3. What CORS header tells the browser which domains can access the resource?
4. When does a browser send a CORS preflight request?
5. What header forces browsers to use HTTPS for all future requests?
Flashcards
Question
How do you set a response header in PHP?
Click to reveal answer
Answer
Use header('Name: Value') function. Must be called before any output. Example: header('Content-Type: application/json');
Question
What is the difference between no-cache and no-store?
Click to reveal answer
Answer
no-cache: Can be cached but must revalidate before use. no-store: Should never be cached at all.
Question
What CORS headers are needed for a Magento REST API?
Click to reveal answer
Answer
Access-Control-Allow-Origin (specific domain), Access-Control-Allow-Methods (GET, POST, PUT, DELETE), Access-Control-Allow-Headers (Content-Type, Authorization), Access-Control-Allow-Credentials (true).
Question
What security headers should every Magento response include?
Click to reveal answer
Answer
X-Content-Type-Options: nosniff, X-Frame-Options: SAMEORIGIN, X-XSS-Protection: 1; mode=block, Strict-Transport-Security: max-age=31536000, Content-Security-Policy.
Question
How do you read the Authorization header in PHP?
Click to reveal answer
Answer
$_SERVER['HTTP_AUTHORIZATION'] or getallheaders()['Authorization']. Parse with preg_match('/Bearer\s+(.+)/', $auth, $matches) for token extraction.
Question
What is a simple request vs preflight request?
Click to reveal answer
Answer
Simple: GET/HEAD/POST with standard headers. Preflight: Any other method or custom headers. Browser sends OPTIONS first for preflight requests.
Question
How do you set ETag caching in PHP?
Click to reveal answer
Answer
header('ETag: "' . md5($content) . '"'); Check with if ($_SERVER['HTTP_IF_NONE_MATCH'] === '"etag"') { http_response_code(304); exit; }
Question
What does Access-Control-Allow-Credentials: true do?
Click to reveal answer
Answer
Allows the browser to send cookies and authentication headers in cross-origin requests. Without this, browsers strip credentials from cross-origin requests.
Revision Notes
Key Takeaways
- 1. Request headers provide metadata about the client's request (Accept, Authorization, Content-Type)
- 2. Response headers control how the client processes the response (Cache-Control, Content-Type)
- 3. Use $_SERVER['HTTP_HEADER_NAME'] or getallheaders() to read request headers
- 4. Use header() function to set response headers (must be called before output)
- 5. CORS headers control cross-origin access: Access-Control-Allow-Origin is the most critical
- 6. Security headers protect against common attacks: XSS, clickjacking, MIME sniffing
Interview Tips
- • Know how to read and set headers in PHP
- • Understand the difference between no-cache and no-store
- • Explain CORS and why preflight requests exist
- • List important security headers and their purposes
- • Understand how Authorization headers work (Bearer, Basic)
Cheat Sheet
HTTP Headers Cheat Sheet
Reading Headers (PHP):
$_SERVER['HTTP_ACCEPT'] // Accept header
$_SERVER['HTTP_AUTHORIZATION'] // Auth header
getallheaders() // All headers as array
Setting Headers (PHP):
header('Content-Type: application/json');
header('Cache-Control: public, max-age=3600');
header('Access-Control-Allow-Origin: https://site.com');
http_response_code(200);
CORS Headers:
- Access-Control-Allow-Origin: Allowed domain
- Access-Control-Allow-Methods: GET, POST, PUT, DELETE
- Access-Control-Allow-Headers: Content-Type, Authorization
- Access-Control-Allow-Credentials: true
Security Headers:
- X-Content-Type-Options: nosniff
- X-Frame-Options: SAMEORIGIN
- Strict-Transport-Security: max-age=31536000
Cache Headers:
- Cache-Control: public, max-age=3600
- ETag: "hash"
- Last-Modified: date