Access Management
Tutorials
How to Protect API Routes

How to Protect API Routes

In a ROQ-generated application, it is crucial to ensure the security of API routes by verifying the user's authorization or role access and permissions. The API is located at src\pages\api.

If you need to add or make changes to an API endpoint and check if the user is authenticated, that is, if the user has logged in and the session is valid, please refer to this documentation.

The authorizationValidationMiddleware() method is responsible for providing this protection in the generated application. It is a wrapper method around hasAccess() API from the @roq\prismajs package and in the generated application you will find this method in the file:

src\server\middlewares\authorization-validation.middleware.ts

For example, this code is protected with user authorization:

// src\pages\api\comments\index.ts
 
import type { NextApiRequest, NextApiResponse } from 'next';
import { prisma } from 'server/db';
import { authorizationValidationMiddleware, errorHandlerMiddleware } from 'server/middlewares';
import { commentValidationSchema } from 'validationSchema/comments';
import { getServerSession } from '@roq/nextjs';
 
async function handler(req: NextApiRequest, res: NextApiResponse) {
  const { roqUserId, user } = await getServerSession(req);
  switch (req.method) {
    case 'POST':
      return createComment();
    default:
      return res.status(405).json({ message: `Method ${req.method} not allowed` });
  }
 
  async function createComment() {
    await commentValidationSchema.validate(req.body);
    const body = { ...req.body };
 
    const data = await prisma.comment.create({
      data: body,
    });
    return res.status(200).json(data);
  }
}
 
export default function apiHandler(req: NextApiRequest, res: NextApiResponse) {
  return errorHandlerMiddleware(authorizationValidationMiddleware(handler))(req, res);
}

The code presented above provides security measures for a POST HTTP request that adds a new comment using createComment() function. Its purpose is to access the route. If you are on local development, it's located at:

http://localhost:3000/comment/create

It assumes that authentication has already been done (that is, the user's identity has been verified), and it focuses on checking whether the authenticated user has the required permissions to perform a certain action.

Let's break it down to the last function in the code, the apiHandler() function:

  1. authorizationValidationMiddleware(handler): This creates a new function that first checks if the user is authorized to perform the requested operation (using authorizationValidationMiddleware), and then, if they are, processes the request using handler.

  2. errorHandlerMiddleware(authorizationValidationMiddleware(handler)): This creates a new function that handles any errors that might be thrown when checking the user's authorization or processing the request.

So the result is a function that does three things: handles errors, checks authorization, and processes the request.

When a request comes in, this function is then called with the request req and response res objects:

errorHandlerMiddleware(authorizationValidationMiddleware(handler))(req, res)