docs: update knowledge base regarding auth checks in page (#23672)

This commit is contained in:
Eunjae Lee
2025-09-15 09:33:06 +00:00
committed by GitHub
parent 18bac4a063
commit e9c6af562e
+49
View File
@@ -319,6 +319,55 @@ dates.map((date) => dayjs.utc(date).add(1, "day").format());
dates.map((date) => new Date(date.valueOf() + 24 * 60 * 60 * 1000));
```
## Next.js App Directory: Authorisation Checks in Pages
This can include checking session.user exists or session.org etc.
### TL;DR:
Dont put permission checks in layout.tsx! Always put them directly inside your page.tsx or relevant server components for every restricted route.
### Why Not to Use Layouts for Permission Checks
* Layouts dont intercept all requests: If a user navigates directly or refreshes a protected route, layout checks might be skipped, exposing sensitive content.
* APIs and server actions bypass layouts: Sensitive operations running on the server cant be guarded by checks in the layout.
* Risk of data leaks: Only page/server-level checks ensure that unauthorized users never get protected data.
### ✅ How To Secure Routes (The Right Way)
* Check permissions inside page.tsx or the actual server component.
* Perform all session/user/role validation before querying or rendering sensitive content.
* Redirect or return nothing to unauthorized users, before running restricted code.
### 🛠️ Example: Page-Level Permission Check
```tsx
// app/admin/page.tsx
import { redirect } from "next/navigation";
import { getUserSession } from "@/lib/auth";
export default async function AdminPage() {
const session = await getUserSession();
if (!session || session.user.role !== "admin") {
redirect("/"); // Or show an error
}
// Protected content here
return <div>Welcome, Admin!</div>;
}
```
### 🧠 Key Reminders
* Put permission guards in every restricted page.tsx.
* Never assume layouts are secure for guarding data.
* Validate users before any sensitive queries or rendering.
## Avoid using Dayjs if you dont need to be strictly tz aware.
When doing logic like Dayjs.startOf(".."), you can instead use date-fns' `startOfMonth(dateObj)` / `endOfDay(dateObj)`;