Svelte / Intermediate: Kit routes and server data policy / Lesson 10
Hooks, endpoints and current object authorization
Establish request-scoped identity in hooks and enforce shared object policy for every server use case.
On this page
Lesson goals
- Explain handle, event.locals and +server endpoint responsibilities.
- Separate cookie transport, authentication, CORS and current domain permission.
locals carries verified context only if the application verifies it
A server handle hook can inspect a request and attach current context to event.locals before resolving it. The property itself is not authentication; a cookie or header remains caller input until the chosen protocol verifies it. Use a reviewed session solution with expiry, revocation and safe failure behavior. Never put currentUser in mutable module-global state that overlapping SSR requests can overwrite. A source service should receive the narrow principal and enforce tenant/object rules again where the effect or private read actually occurs. This keeps protection shared across loads, actions and endpoints rather than relying on one layout or route shape.
Establish a request-owned principal without a global variable
The hook fragment verifies one session cookie and writes the result to this event’s locals. It does not implement the verifier, cookie rotation or role refresh. resolve continues Kit’s processing under the selected server contract. The actual hook may be composed with others, so review order and response transformations deliberately. A +server handler using that principal remains an independent HTTP endpoint and needs input, output and method rules. It does not automatically inherit a page’s form-action or layout behavior. No hook, cookie read or endpoint is executed by this course.
// src/hooks.server.js
export async function handle({event,resolve}) {
const credential=event.cookies.get("session");
event.locals.principal=await sessions.verifyCurrent(credential);
return resolve(event);
}
sessions is an unexecuted reviewed dependency. No credential, route or response is processed here.
Protect the object rather than only the page URL
A course can be reached through a list, direct load, action result or endpoint. Apply the same current eligibility rule across those paths and define whether absent/denied objects share a safe public result. An ID in params or FormData identifies requested scope, not permission. HTTP method checks, CORS headers and cookie attributes also solve different problems. CORS governs browser response reading and does not authenticate a non-browser client or replace CSRF protection for automatically attached credentials. Keep request origin, verified principal and domain action distinct rather than expanding allowed origins to fix a session error.
Check independent prerequisites with the same object
The local predicate permits a synthetic edit only for a nonexpired editor in the same tenant. It rejects a cross-tenant editor and an expired same-tenant editor at the exact deadline. Real policy may also include ownership or enrollment, and authentication must establish the trusted inputs. This is not a Kit hook or cryptographic session test. A service spy should separately prove that denied calls never reach a write. Keep safe public categories and controlled internal correlation rather than returning token contents or private policy diagnostics to the caller.
function mayEdit(p,course,now){return p.tenant===course.tenant && p.roles.includes("editor") && now<p.expires;}
const course={id:"c1",tenant:"lab-a"};
console.assert(mayEdit({tenant:"lab-a",roles:["editor"],expires:1000},course,999));
console.assert(!mayEdit({tenant:"lab-b",roles:["editor"],expires:1000},course,999));
console.assert(!mayEdit({tenant:"lab-a",roles:["editor"],expires:1000},course,1000));
The declared three prerequisites are checked locally. No session, hook, endpoint or durable write is exercised.
Retire authority and private results coherently
Logout should retire server authority and clear the matching cookie under the session design, while client caches and pending results must not reveal the previous account. A browser cookie disappearing does not alone prove a stolen identifier was revoked at the server. Verify current role and source requirements for sensitive operations instead of keeping copied privileges forever. This course runs only the policy predicate; hooks, cookie serialization, authentication, CORS, CSRF and HTTP endpoint behavior remain unexecuted. Actual verification needs safe synthetic principals through every intended server entry in an authorized isolated project, including account switches while requests are pending.
Common errors and fixes
An arbitrary cookie becomes a trusted principal
- Why it happens
- Credential transport was mistaken for successful verification.
- How to fix it
- Apply the actual session protocol before populating trusted locals.
- Prevent it next time
- Test invalid, missing, expired and revoked authority separately.
A server-global currentUser mixes SSR callers
- Why it happens
- Request identity outlived its owning event and became shared mutable state.
- How to fix it
- Keep principal state event-owned and pass explicit context.
- Prevent it next time
- Test overlapping principals and late results.
A protected page has an unprotected direct endpoint
- Why it happens
- UI gating replaced shared object policy.
- How to fix it
- Enforce eligibility inside every server entry/use case.
- Prevent it next time
- Test list, load, action and endpoint paths for the same object.
Check your understanding
1. Does event.locals authenticate its own principal value?
Show worked solution
No. It is a request-context container. The application must verify the credential and place a trusted current principal there. The service must still apply object policy. Test the verifier and each policy boundary separately rather than treating the property name as a security guarantee.
2. Why is cookie deletion different from server-side revocation?
Show worked solution
Deletion removes the browser’s local transport value under matching attributes, while a copied identifier may still be valid in the server store. Retire that authority through the reviewed session protocol and verify expiry/revocation independently. Keep private client state and pending old-principal results aligned with the new identity.
Key takeaways
- Hooks establish request context; services enforce object authority.
- Cookie, origin and principal evidence are different layers.