Documentation Index
Fetch the complete documentation index at: https://docs.go-mizu.dev/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The xrequestedwith middleware validates the X-Requested-With header, commonly used to identify AJAX requests and prevent CSRF attacks.
Use it when you need:
- AJAX request validation
- CSRF protection layer
- Request origin verification
Installation
import "github.com/go-mizu/mizu/middlewares/xrequestedwith"
Quick Start
app := mizu.New()
// Require X-Requested-With: XMLHttpRequest
app.Use(xrequestedwith.New())
Configuration
Options
| Option | Type | Default | Description |
|---|
Required | bool | true | Require header |
Value | string | "XMLHttpRequest" | Expected value |
Methods | []string | State-changing | Methods to check |
Examples
Basic Validation
app.Use(xrequestedwith.New())
// Requires: X-Requested-With: XMLHttpRequest
Custom Value
app.Use(xrequestedwith.New(xrequestedwith.Options{
Value: "MyApp",
}))
// Requires: X-Requested-With: MyApp
Specific Methods
app.Use(xrequestedwith.New(xrequestedwith.Options{
Methods: []string{"POST", "PUT", "DELETE"},
}))
Detection Only
app.Use(xrequestedwith.New(xrequestedwith.Options{
Required: false, // Don't reject, just detect
}))
app.Get("/", func(c *mizu.Ctx) error {
if xrequestedwith.IsAJAX(c) {
return c.JSON(200, data)
}
return c.HTML(200, page)
})
API Reference
Functions
// New creates X-Requested-With middleware
func New(opts ...Options) mizu.Middleware
// IsAJAX returns true if AJAX request
func IsAJAX(c *mizu.Ctx) bool
Client Usage
// jQuery sets this automatically
$.ajax({url: '/api', type: 'POST', data: data});
// Fetch/XMLHttpRequest
fetch('/api', {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
});
Technical Details
Implementation Overview
The middleware performs header validation through the following process:
- Method Filtering: Checks if the request method is in the skip list (default: GET, HEAD, OPTIONS)
- Path Filtering: Checks if the request path is in the skip paths list
- Header Validation: Compares the X-Requested-With header value (case-insensitive) against the expected value
- Error Handling: Returns either a custom error handler response or a default 400 Bad Request
Internal Components
- Skip Methods Map: Pre-built map of HTTP methods to skip (defaults to safe methods)
- Skip Paths Map: Pre-built map of paths to exclude from validation
- Case-Insensitive Comparison: Uses
strings.EqualFold for header value matching
- Default Value: “XMLHttpRequest” is used when no custom value is specified
Function Variants
| Function | Purpose | Skip Methods |
|---|
New() | Standard validation | GET, HEAD, OPTIONS |
WithOptions() | Custom configuration | Configurable |
Require(value) | Custom value validation | GET, HEAD, OPTIONS |
AJAXOnly() | Strict AJAX validation | None (checks all methods) |
IsAJAX() | Detection helper | N/A (utility function) |
Security Note
While X-Requested-With adds a layer of protection, it should not be the sole CSRF defense. Combine with:
- CSRF tokens
- SameSite cookies
- Origin validation
Best Practices
- Use as additional security layer
- Combine with CSRF middleware
- Don’t rely on it alone
- Document header requirement for clients
Testing
The middleware includes comprehensive test coverage for various scenarios:
| Test Case | Description | Expected Behavior |
|---|
| TestNew - with header | POST request with X-Requested-With: XMLHttpRequest | Returns 200 OK |
| TestNew - without header | POST request without X-Requested-With header | Returns 400 Bad Request |
| TestNew_SkipsGET | GET request without header (default skip) | Returns 200 OK (skipped validation) |
| TestWithOptions_CustomValue - correct value | Request with custom header value “CustomValue” | Returns 200 OK |
| TestWithOptions_CustomValue - wrong value | Request with XMLHttpRequest when CustomValue expected | Returns 400 Bad Request |
| TestWithOptions_SkipPaths - skipped path | POST to /webhook (in skip list) without header | Returns 200 OK (path skipped) |
| TestWithOptions_SkipPaths - non-skipped path | POST to /api (not in skip list) without header | Returns 400 Bad Request |
| TestWithOptions_ErrorHandler | Request without header with custom error handler | Returns 403 Forbidden with custom JSON |
| TestRequire | Request with custom required value “FetchRequest” | Returns 200 OK |
| TestAJAXOnly - with AJAX header | GET request with XMLHttpRequest header | Returns 200 OK |
| TestAJAXOnly - without AJAX header | GET request without header (no methods skipped) | Returns 400 Bad Request |
| TestIsAJAX - is AJAX | Request with X-Requested-With: XMLHttpRequest | IsAJAX() returns true |
| TestIsAJAX - not AJAX | Request without X-Requested-With header | IsAJAX() returns false |
| TestCaseInsensitive | POST with lowercase “xmlhttprequest” | Returns 200 OK (case-insensitive match) |
- csrf - CSRF protection
- cors - CORS handling
- bot - Bot detection