Auth & Guards¶
Add lightweight auth/guard logic across bindings. Prefer middleware/hooks for cross-cutting checks.
Token check middleware¶
from spikard import Spikard
app = Spikard()
@app.pre_handler
async def auth_hook(request: dict[str, object]):
headers = request.get("headers", {}) if isinstance(request, dict) else {}
token = headers.get("authorization") if isinstance(headers, dict) else None
if token != "Bearer dev-token":
return {"error": "unauthorized"}, 401
return request
import { Spikard, type Request } from "spikard";
interface JWTPayload {
sub: string;
iat: number;
exp: number;
}
const app = new Spikard();
app.onRequest(async (request: Request): Promise<Request | { statusCode: number; body: unknown }> => {
const token = request.headers["authorization"];
if (token !== "Bearer dev-token") {
return { statusCode: 401, body: { error: "unauthorized" } };
}
// Parse and validate JWT payload with proper typing
const payload = JSON.parse(token.split(".")[1]) as JWTPayload;
request.user = payload;
return request;
});
<?php
declare(strict_types=1);
use Spikard\App;
use Spikard\Config\ServerConfig;
use Spikard\Config\LifecycleHooks;
use Spikard\Config\HookResult;
use Spikard\Http\Request;
use Spikard\Http\Response;
$hooks = LifecycleHooks::builder()
->withPreHandler(function (Request $request): HookResult {
$token = $request->headers['authorization'] ?? null;
if ($token !== 'Bearer dev-token') {
return HookResult::shortCircuit(
Response::json(['error' => 'unauthorized'], 401)
);
}
return HookResult::continue();
})
->build();
$app = (new App(new ServerConfig(port: 8000)))
->withLifecycleHooks($hooks);
Tips¶
- Normalize header casing before checks (bindings expose lowercased headers).
- Short-circuit unauthorized requests with a structured body.
- Add per-route middleware for sensitive endpoints (admin, payments).