Why this lesson matters
Understand authentication boundaries and use it correctly in an App Router project. Authentication proves identity while authorization protects data and mutations. Sessions and cookies transport trusted state, but server code must interpret that state at each protected boundary.
How to reason about it
- For Authentication Boundaries, the outcome to verify is: Do not rely on hiding a client button; final authorization must be enforced on the server.
- In Authentication Boundaries, keep this failure controlled: Checking authentication in navigation or middleware alone does not protect a server function that can still be called through another path.
- Authentication Boundaries practice target: Create a protected data function that distinguishes unauthenticated from forbidden access and call it from a server-rendered route.
Authentication and authorization boundary
Request
Practical walkthrough
In the Authentication Boundaries walkthrough: Do not rely on hiding a client button; final authorization must be enforced on the server.
authorization.tstypescript
export async function requireProjectAccess(projectId: string) {
const session = await getSession();
if (!session) throw new Error('UNAUTHENTICATED');
if (!(await canAccessProject(session.userId, projectId))) throw new Error('FORBIDDEN');
}Practice it yourself
Authentication Boundaries exercise
Create a protected data function that distinguishes unauthenticated from forbidden access and call it from a server-rendered route.
- Record the expected result before execution
- Test one valid path and one lesson-specific failure path
- Explain in two lines which boundary owns the decision
