• Blog
  • Documentation
  • Courses
  • Changelog
  • AI Starters
  • UI Kit
  • FAQ
  • Supamode
    New
  • Pricing

Launch your next SaaS in record time with Makerkit, a React SaaS Boilerplate for Next.js and Supabase.

Makerkit is a product of Makerkit Pte Ltd (registered in the Republic of Singapore)Company Registration No: 202407149CFor support or inquiries, please contact us

About
  • FAQ
  • Contact
  • Verify your Discord
  • Consultation
  • Open Source
  • Become an Affiliate
Product
  • Documentation
  • Blog
  • Changelog
  • UI Blocks
  • Figma UI Kit
  • AI SaaS Starters
License
  • Activate License
  • Upgrade License
  • Invite Member
Legal
  • Terms of License
    • Adding API Routes
    • Change Authentication strategy
    • Fetching the signed in User
    • Reading a Document
    • Creating a Document
    • Configuring Plans
    • Project Configuration
    • Updating the Navigation menu
    • Adding a new translation string
    • Guarding an API Route
    • Adding Pages
    • Updating the Sidebar menu
    • Require Email Verification
    • Fetching the selected Organization
    • Reading a list of Documents
    • Updating a Document
    • Running the Stripe Webhook locally
    • Branding
    • Setting a Default Language
    • Dark Theme
    • Theming
    • Calling API Routes from the client
    • Deleting a Document
    • Updating the Logo
    • Adding a new language in the Next.js Firebase SaaS Kit
    • Checking CSRF Tokens
    • Passing data from server to client
    • Updating the Fonts
    • Adding Pages
    • Guarding Pages
    • Using Lemon Squeezy instead of Stripe
    • Updating the Favicons
    • Using the Language Switcher
    • Environment variables
    • Detect current Locale
    • Setting up Emails

Guarding an API Route

It's very likely that you want to ensure only authenticated users can access your API routes. To do that, you can use the withAuth HOC to wrap your API route handler.

pages/api/hello.ts
import { NextApiRequest, NextApiResponse } from "next";
import { withAuthedUser } from '~/core/middleware/with-authed-user';
function helloWorldHandler(req: NextApiRequest, res: NextApiResponse) {
res.status(200).json({ text: 'Hello' })
}
export default withAuthedUser(
helloWorldHandler
);

When using the withAuthedUser HOC, the req.firebaseUser object will be available in your API route handler. This object contains the user's information from their Firebase Auth account.

You can use this object to retrieve data from your database, or to perform other actions, based on the user's information.

Guarding an API Route with a Custom Middleware

If you want to use a custom middleware to guard your API route, you can do so fairly easily by using a function that accepts a handler function and returns a handler function.

Example: Guarding an API Route based on the User's Role

Let's say we want to create a function that guards an API route based on the user's role. We can do that by creating a function that accepts a role as an argument, and returns a handler function that checks the user's role before executing the handler function.

Important: this middleware requires that the withAuthedUser middleware is used before it - otherwise, the req.firebaseUser object will not be available.

core/middleware/with-role.ts
import { NextApiRequest,NextApiResponse } from "next";
import { MembershipRole } from '~/lib/organizations/types/membership-role';
import { getCurrentOrganization } from '~/lib/server/organizations/get-current-organization';
export function withRole(role: MembershipRole) {
return async function(req: NextApiRequest, res: NextApiResponse) {
const userId = req.firebaseUser.uid;
const currentOrganizationId = req.cookies.organizationId;
const organization =
await getCurrentOrganization(userId, currentOrganizationId);
const currentUserRole = organization.members[userId].role;
if (currentUserRole !== role) {
return res.status(403).json({
error: 'You do not have permission to access this resource.'
});
}
};
}

Now, we can use this middleware in our API route handler.

pages/api/hello.ts
import { NextApiRequest, NextApiResponse } from "next";
import { MembershipRole } from '~/lib/organizations/types/membership-role';
import { withAuthedUser } from '~/core/middleware/with-authed-user';
import { withRole } from '~/core/middleware/with-role';
import { withPipe } from '~/core/middleware/with-pipe';
function helloWorldHandler(req: NextApiRequest, res: NextApiResponse) {
res.status(200).json({ text: 'Hello' })
}
export default withPipe(
withAuthedUser,
withRole(MembershipRole.Admin),
helloWorldHandler,
);

Example: Guarding an API Route based on the Organization's Status

Let's say we want to create a function that guards an API route based on the organization's status.

Important: this middleware requires that the withAuthedUser middleware is used before it - otherwise, the req.firebaseUser object will not be available.

core/middleware/with-active-subscription.ts
import { NextApiRequest,NextApiResponse } from "next";
import { getCurrentOrganization } from '~/lib/server/organizations/get-current-organization';
export function withActiveSubscription() {
return async function(req: NextApiRequest, res: NextApiResponse) {
const userId = req.firebaseUser.uid;
const currentOrganizationId = req.cookies.organizationId;
const organization =
await getCurrentOrganization(userId, currentOrganizationId);
const status = organization.subscription?.status;
const isActive = ['active', 'trialing'].includes(status);
if (!isActive) {
return res.status(403).json({
error: 'You do not have permission to access this resource.'
});
}
};
}

Now, we can use this middleware in our API route handler.

pages/api/hello.ts
import { NextApiRequest, NextApiResponse } from "next";
import { withAuthedUser } from '~/core/middleware/with-authed-user';
import { withActiveSubscription } from '~/core/middleware/with-active-subscription';
import { withPipe } from '~/core/middleware/with-pipe';
function helloWorldHandler(req: NextApiRequest, res: NextApiResponse) {
res.status(200).json({ text: 'Hello' })
}
export default withPipe(
withAuthedUser,
withActiveSubscription,
helloWorldHandler,
);
On this page
  1. Guarding an API Route with a Custom Middleware
    1. Example: Guarding an API Route based on the User's Role
    2. Example: Guarding an API Route based on the Organization's Status