Skip to content

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;
});
require "spikard"

app = Spikard::App.new

app.pre_handler do |request|
  headers = request[:headers] || {}
  if headers["authorization"] != "Bearer dev-token"
    { error: "unauthorized" }
  else
    request
  end
end
<?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);
use spikard::prelude::*;
use tower_http::auth::RequireAuthorizationLayer;

let mut app = App::new();

app.layer(RequireAuthorizationLayer::bearer("dev-token"));

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).