Central vs per-route token validation in Astro middleware for expired credentials
0 reputation · 30 Oct 2023, 11:31 UTC
0 reputation · 30 Oct 2023, 11:31 UTC
Goal is to enforce least-privilege authentication in an Astro app using documented middleware as the integration point for auth checks, with expired credentials rejected consistently across server-rendered pages and endpoints.
Astro has no built-in authentication. Middleware defined in src/middleware.ts runs only for SSR-rendered routes and can validate a session or token, attach a minimal identity to context.locals, and return a Response for expired or invalid credentials. Endpoints can return raw Response objects for 401/403. Static prerendered pages do not execute middleware per request.
The unresolved design choice is whether to validate and refresh tokens centrally in middleware or perform checks per route. Central validation simplifies handling of expired credentials but couples routes to a single strategy and may expose more identity than needed. Per-route checks support finer least-privilege but risk inconsistent expiry handling.
Which pattern preserves least-privilege while ensuring expired credentials are rejected uniformly across SSR pages and Astro endpoints? Does attaching a minimal identity in middleware remove the need for per-route expiry checks? When output mixes static and server-rendered routes, how should expired credential handling be documented to avoid gaps on prerendered pages?
33275 reputation · 30 Oct 2023, 15:43 UTC
Use central token expiry validation in src/middleware.ts for all SSR routes and Astro endpoints, and keep per-route authorization only. Attach a minimal identity to context.locals in middleware. That gives uniform rejection of expired credentials for SSR pages and endpoints while preserving least-privilege, because routes never re-validate expiry, only scope access using the minimal identity.
For mixed static + SSR output, treat prerendered pages as a build-time boundary: any route with prerender: true must be public or guarded client-side. Document that explicitly. Central middleware alone does not protect prerendered pages.
src/middleware.ts runs only for SSR-rendered routes and API endpoints, not for prerendered static pages.Response for 401/403, and attach data to context.locals.Response objects.Central expiry enforcement is the reliable way to ensure uniform rejection. Per-route expiry checks create inconsistency and drift.
A hybrid is least-privilege compatible:
context.locals.user = { userId, role } only. No full profile.context.locals.user for fine-grained authorization, e.g., role or resource ownership.Attaching a minimal identity removes the need for per-route expiry re-checks for SSR routes, because expiry is guaranteed by middleware before the handler runs. Per-route checks remain only for authorization scope, not authentication validity.
export const prerender = true.context.locals.user is present only after successful central validation; handlers must not assume it exists for prerendered routes.context.locals in a handler to confirm only userId and role are present.astro build and serve output, request a prerendered protected page with an expired cookie; confirm static HTML is served, demonstrating the middleware gap.Missing diagnostic detail that would change the recommendation: are the protected pages currently configured with prerender: true or served via static output? If yes, central middleware cannot protect them and a client-side guard or SSR switch is required.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.