Learn how to implement permission control and access control in ShipNowKit frontend applications.
We've already covered how to implement access control in API routes. This guide will show you how to protect pages and display UI based on user roles or permissions.
Protecting Routes (Server-Side)
Authenticated Users Only
To protect a route so that only authenticated users can access it, you can get the session in an RSC component and check if the user is authenticated.
import { getSession } from "@/lib/actions/auth";
import { redirect } from "next/navigation";
export default async function MyProtectedPage() {
const session = await getSession();
if (!session) {
redirect("/signin");
}
return <div>Protected page</div>;
}Tip: If you check the session in a layout component (layout.tsx), all child pages under that layout will automatically be protected, eliminating the need to repeat the check in each page component.
Admin Users Only
To check if a user has the necessary permissions to access a page, for example, you can make a page accessible only to users with admin permissions.
ShipNowKit uses the environment variable ADMIN_USER_LIST to configure the admin user list:
# .env.local
ADMIN_USER_LIST=user_id_1,user_id_2,user_id_3Check admin permissions in server components:
import { getSession } from "@/lib/actions/auth";
import { isCurrentUserAdmin } from "@/lib/admin";
import { redirect } from "next/navigation";
export default async function MyAdminPage() {
const session = await getSession();
if (!session) {
redirect("/signin");
}
const isAdmin = await isCurrentUserAdmin();
if (!isAdmin) {
redirect("/?error=access_denied");
}
return <div>This page is only accessible to administrators</div>;
}Using the requireAdmin Function
ShipNowKit provides a requireAdmin function that throws an error if the user is not an admin:
import { requireAdmin } from "@/lib/admin";
export default async function MyAdminPage() {
await requireAdmin(); // Throws an error if not an admin
return <div>This page is only accessible to administrators</div>;
}Checking Specific User ID
You can also check if a specific user ID is an admin:
import { isUserAdmin } from "@/lib/admin";
export default async function MyPage() {
const session = await getSession();
if (!session) {
redirect("/signin");
}
const isAdmin = await isUserAdmin(session.user.id);
if (!isAdmin) {
return <div>Access denied</div>;
}
return <div>Admin content</div>;
}Displaying UI Based on Permissions (Client-Side)
On the client side, you can use the useSession hook to get the session and then check if the user has the necessary permissions.
Authenticated Users
import { useSession } from "@/lib/auth-client";
export function MyComponent() {
const { data: session, isPending } = useSession();
if (isPending) {
return <div>Loading...</div>;
}
if (!session) {
return <div>You need to sign in to access this page</div>;
}
return <div>You are signed in</div>;
}Note: You should always check permissions on the server side first to avoid any security issues.
Admin Users
import { useSession } from "@/lib/auth-client";
import { isUserAdmin } from "@/lib/admin";
import { useEffect, useState } from "react";
export function MyComponent() {
const { data: session } = useSession();
const [isAdmin, setIsAdmin] = useState(false);
useEffect(() => {
if (session?.user?.id) {
isUserAdmin(session.user.id).then(setIsAdmin);
}
}, [session]);
if (!isAdmin) {
return <div>This page is only accessible to administrators</div>;
}
return <div>Admin content</div>;
}Using the SignedIn Component
For simple authentication checks, you can use the SignedIn component:
import { SignedIn } from "@/components/auth/SignedIn";
export function MyComponent() {
return (
<SignedIn>
<div>Only signed-in users can see this content</div>
</SignedIn>
);
}User and Session Management
Learn how to access user and session information in ShipNowKit applications. Guide for using useSession hook and getSession function for authentication state management.
OAuth Configuration
Learn how to configure OAuth providers in your ShipNowKit application. Step-by-step guide for setting up Google, GitHub, Discord, Facebook, and Twitter OAuth.