export default authMiddleware()
That’s it. One line in your middleware file and your Next.js app has authentication — sign-up, sign-in, sign-out, session management, and protected routes. No wrestling with JWTs, no hand-rolling session logic, no third-party cookie headaches. Just drop it in and move on.
We built MonoGrub, a sample food ordering app, to show what this looks like in a real project. It’s open source, runs locally in five minutes, and covers the auth patterns you’ll actually need in production. Let’s walk through what it does.
One Line, Full Auth
When you call authMiddleware(), MonoCloud handles the entire OpenID Connect flow behind the scenes — redirects, token exchange, cookie-based sessions, silent refresh. Your users get a polished sign-up and sign-in experience, and you don't write a single line of auth plumbing.
But the real power shows up when you need more control. Want to lock down your admin section to a specific group of users? Pass a config:
export default authMiddleware({
protectedRoutes: [
{ routes: ["/admin"], groups: ["admin"] }
],
});
That’s role-based access control, declared at the middleware layer, with zero custom logic in your page components. Add more routes, more groups, more rules — it’s all configuration, not code. By default, unauthorized users get a 403. Want something friendlier? Add an onGroupAccessDenied handler to redirect them wherever you like — MonoGrub sends them to a custom access-denied page.
Protecting Routes, APIs and UI
Authentication tells you who someone is. But most apps need to go further — you need to control what they can do. MonoGrub demonstrates this across every layer of a Next.js app.
Server Actions — Every sensitive operation in MonoGrub starts with a call to protect(). This validates the user's session server-side before any business logic runs. If the session is expired or invalid, the user is redirected to the sign-in page. No ambiguity, no race conditions.
API Routes — MonoGrub’s API endpoints use a protectApi() helper that gates access by auth status or group membership. The user's identity comes from the server-side session — not from anything the client submits — which eliminates an entire class of spoofing vulnerabilities.
Pages — For pages that require authentication, MonoGrub wraps them with protectPage(). If an unauthenticated user tries to access a protected page, they're automatically redirected to sign in — no manual checks or redirect logic needed in your component.
UI Components — Not everything needs a full page redirect. MonoGrub uses the client-side <Protected> component to conditionally render UI based on auth status. For example, the "Place Order" button is wrapped in <Protected> with a fallback that prompts the user to sign in. Authenticated users see the button; everyone else sees a sign-in prompt — no useEffect, no loading flicker, no auth state wiring.
The pattern is consistent: declare your access rules up front, and let MonoCloud enforce them. Your application code stays focused on what it’s actually supposed to do.
Profile Management, Without a User Table
Once your users are signed in, they’ll want to manage their accounts. MonoGrub handles profile updates — name changes, password resets — entirely through MonoCloud’s Management SDK. There’s no custom user table to maintain, no password hashing to get right, no “forgot password” flow to build from scratch.
Updating a user’s name is a single SDK call. Changing a password is another. After any update, we refresh the session so the UI stays in sync.
This is the kind of feature that’s easy to underestimate. It’s not glamorous, but building it from scratch is months of work you’ll never get back. With MonoCloud, it’s already done.
What MonoGrub Covers
To recap, here’s what you’ll find in the sample app:
- Sign-up, sign-in, sign-out powered by MonoCloud’s OIDC flow
- Route protection via middleware — both auth-required and role-required
- Admin dashboard gated by group membership
- Profile management using the Management SDK (name updates, password changes)
- Protected API routes with server-side identity verification
- Role-based UI — the navbar adapts based on the user’s group membership
Get It Running
Clone the repo, create a free MonoCloud account, add your credentials, and start the dev server:
git clone https://github.com/monocloud/monogrub-nextjs-demo.git
cd monogrub-nextjs-demo
npm install
Create a .env.local file in the project root with your MonoCloud credentials:
MONOCLOUD_AUTH_TENANT_DOMAIN=<your-tenant-domain>
MONOCLOUD_AUTH_CLIENT_ID=<your-client-id>
MONOCLOUD_AUTH_CLIENT_SECRET=<your-client-secret>
MONOCLOUD_AUTH_SCOPES=openid profile email groups
MONOCLOUD_AUTH_APP_URL=http://localhost:3000
MONOCLOUD_AUTH_COOKIE_SECRET=<your-cookie-secret>
MONOCLOUD_AUTH_REFETCH_USER_INFO=true
MONOCLOUD_AUTH_REFETCH_STRICT_PROFILE_SYNC=true
MONOCLOUD_API_KEY=<your-monocloud-api-key>
Then fire it up:
npm run dev
Open http://localhost:3000, and you’ve got a fully authenticated app running locally.
Ship Auth, Don’t Build It
Every hour you spend building authentication is an hour you’re not spending on your product. MonoCloud gives you production-grade auth with minimal integration effort — start with one line of middleware, and scale up to protected routes, RBAC, and user management as you need them.
Explore the source, adapt the patterns, and ship.
Want to dig deeper? Start with the MonoCloud Docs, explore the Management SDK, or clone MonoGrub and start hacking.
Top comments (0)