This guide shows how to protect API routes in a Next.js Pages Router application using protectApi().
Protected API routes require authentication and can optionally enforce group-based authorization.
protectApi()This guide assumes you’ve completed the Next.js Pages Router quickstart.
You should already have:
pages/ directory).env.localCreate an API route and wrap the handler with protectApi().
import { protectApi } from "@monocloud/auth-nextjs";
import { NextApiRequest, NextApiResponse } from "next";
export default protectApi((_req: NextApiRequest, res: NextApiResponse) => {
res.status(200).json({
message: "You have accessed a protected endpoint",
});
});
How it works:
protectApi() runs on every requestYou can require users to belong to specific groups before accessing an API route.
groups to the application scopes.env.local:MONOCLOUD_AUTH_SCOPES=openid profile email groups
After updating scopes, users must sign out and sign back in for the new claims to be included in their session.
import { protectApi } from "@monocloud/auth-nextjs";
import { NextApiRequest, NextApiResponse } from "next";
export default protectApi(
(_req: NextApiRequest, res: NextApiResponse) => {
res.status(200).json({ message: "Admin-only data" });
},
{
groups: ["admin"],
}
);
To customize the response when a user is not authenticated, pass the onAccessDenied option.
import { protectApi } from "@monocloud/auth-nextjs";
import { NextApiRequest, NextApiResponse } from "next";
export default protectApi(
(_req: NextApiRequest, res: NextApiResponse) => {
res.status(200).json({ message: "Protected data" });
},
{
onAccessDenied: (_req, res) => {
res.status(401).json({
error: "unauthorized",
message: "Please sign in"
});
}
}
);
How it works:
To customize the response when a user is authenticated but does not belong to the required group, pass the onGroupAccessDenied option.
import { protectApi } from "@monocloud/auth-nextjs";
import { NextApiRequest, NextApiResponse } from "next";
export default protectApi(
(_req: NextApiRequest, res: NextApiResponse) => {
res.status(200).json({ message: "Admin-only data" });
},
{
groups: ["admin"],
onGroupAccessDenied: (_req, res, user) => {
res.status(403).json({
error: "forbidden",
message: `User ${user.email} does not have access to this resource.`
});
}
}
);
How it works:
onAccessDenied).onGroupAccessDenied).Protect other parts of your application: