enlivenapp / flight-csrf
CSRF protection middleware and helpers for FlightPHP
Package info
github.com/enlivenapp/FlightPHP-CSRF
Type:flightphp-foundation
pkg:composer/enlivenapp/flight-csrf
Requires
- php: ^8.1
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
flight-csrf
CSRF protection middleware and helpers for FlightPHP.
Requirements
- PHP 8.1+
Installation
composer require enlivenapp/flight-csrf
Setup
After installing, register the plugin to load the helper functions and scaffold default config:
use Enlivenapp\FlightCsrf\Plugin; $plugin = new Plugin(); $plugin->register(Flight::app(), Flight::router());
Call this early in your bootstrap, before defining routes. register() does two things: it requires the helper file that defines csrf_field() and csrf_token(), and it writes default config keys into app/config/config.php if they're missing.
If you'd rather set things up yourself, skip register() and do the following instead:
- Require
vendor/enlivenapp/flight-csrf/src/Helpers/csrf_helper.phpfrom your bootstrap. - Add the config block manually (see Configuration below).
Usage
Forms
Call csrf_field() to output a hidden input in any HTML form. The token is generated and stored in the session automatically.
<form method="POST" action="/login"> <?= csrf_field() ?> <input type="text" name="username"> <button type="submit">Log in</button> </form>
AJAX requests
Call csrf_token() to get the raw token value. The common pattern is to embed it in a meta tag and read it from JavaScript.
<meta name="csrf-token" content="<?= csrf_token() ?>">
fetch('/api/resource', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content, }, body: JSON.stringify({ foo: 'bar' }), });
The middleware accepts the token from either the _csrf_token POST field or the X-CSRF-TOKEN request header. The POST field is checked first.
Protecting routes
Apply CsrfMiddleware to any route or route group that needs protection:
use Enlivenapp\FlightCsrf\Middlewares\CsrfMiddleware; Flight::route('POST /login', function () { // ... })->addMiddleware(new CsrfMiddleware(Flight::app())); // Or protect a group Flight::group('/admin', function () { Flight::route('POST /save', function () { /* ... */ }); Flight::route('DELETE /remove/@id', function ($id) { /* ... */ }); }, [new CsrfMiddleware(Flight::app())]);
When validation fails the middleware halts the request with a 403 response. The body is {"error":"CSRF token validation failed."} as JSON.
Configuration
Config lives under the enlivenapp.flight-csrf key. Defaults are in src/Config/Config.php. Override them in your app config, and values are merged on top of the defaults.
| Key | Default | Description |
|---|---|---|
field_name |
_csrf_token |
Name of the hidden form field |
session_key |
_csrf_token |
Session key used to store the token |
protected_methods |
['POST','PUT','PATCH','DELETE'] |
HTTP methods that trigger validation |
exclude_routes |
[] |
Request paths to skip (exact URI match, no query string) |
token_lifetime |
7200 |
Seconds from creation before the token expires. 0 disables time-based expiry. Expired tokens fail validation (403) and rotate on the next csrf_token() or csrf_field() call. |
Overriding defaults
When Plugin::register() runs for the first time, it writes token_lifetime and exclude_routes into your config file so you can edit them in place. You can add any other key to the same block.
// app/config/config.php return [ // ... 'enlivenapp.flight-csrf' => [ 'token_lifetime' => 3600, 'exclude_routes' => [ '/webhooks/stripe', '/api/public/callback', ], ], ];
License
MIT