Question presented to candidate: "How would you implement authentication and authorization in a Next.js App Router app, and where exactly should the checks live?"
What a strong answer should cover:
- Use a session: a signed, encrypted cookie (stateless) or a session id backed by a database; auth libraries (Auth.js, Clerk, Better Auth and others) handle the details.
- Proxy (formerly middleware) is good for optimistic redirects based on the cookie, not for full authorization.
- Verify the session close to the data: a data access layer (DAL) function, wrapped in React
cache, called by pages, Server Actions and Route Handlers. - Do not rely on layouts: they do not re-render on client navigation, so a layout check can be skipped; pages and layouts also render in parallel.
- Every Server Action and Route Handler must check the session itself, because they are public endpoints.
Clarifying questions expected:
- "Stateless cookie or database sessions?" β decides revocation and scaling trade-offs.
- "Is there role-based access?" β authorization checks belong in the data layer.
Code / implementation expected: Yes β a DAL with a cached session check, and its use in a page and an action.