Understanding the Security Framework

APIs Endpoint/GPTs Actions : The GPT-Todo Demo

When creating new API endpoints in the app/api folder, use the auth middleware to secure the endpoint. This ensures that only authenticated and authorized users can access the protected resources. By applying the auth middleware consistently across your API endpoints, you maintain a secure and reliable API system.

This documentation provides an overview of the API endpoint for the Todo Demo Example, which showcases authorization and security using the auth middleware in the API.

//app/api/todo-demo/route.ts

import { NextRequest, NextResponse } from 'next/server';
import prisma from '@/utils/prisma.service';
import { authMiddleware } from '@/middleware/oauthMiddleware';
import { incrementApiCallCount, getApiCallCount } from '@/utils/gpts-ouath-functions/functions';
import { API_USAGE_LIMITS_BY_CLIENT_ID } from '@/constants';
import { logApiCalls } from '@/middleware/logApiCalls'; 

export async function POST(request: NextRequest) {
  const userInfo = await authMiddleware(request);
  if (userInfo instanceof NextResponse) {
    return userInfo;
  }

  const { title, description, status } = await request.json();
  const userId = userInfo.id;
  const clientId = userInfo.cid;

  try {
    const currentApiCallCount = await getApiCallCount(userId, clientId);
    userInfo.api_call_count = currentApiCallCount;

    const maxApiCallLimit = API_USAGE_LIMITS_BY_CLIENT_ID[clientId];
    if (currentApiCallCount >= maxApiCallLimit) {
      const errorResponse = NextResponse.json({ error: 'You have reached the maximum number of free API calls.' }, { status: 429 });
      await logApiCalls(request, errorResponse, userInfo); 
      return errorResponse;
    }

    const todo = await prisma.todo.create({
      data: {
        title,
        description,
        status,
        userId,
      },
    });

    // Increment call count and update userInfo
    const updatedApiCallCount = await incrementApiCallCount(userId, clientId);
    userInfo.api_call_count = updatedApiCallCount;

    const response = NextResponse.json(todo);
    await logApiCalls(request, response, userInfo); 
    return response;  
  } catch (error) {
    const errorResponse = NextResponse.json({ error: 'Failed to create todo item' }, { status: 500 });
    await logApiCalls(request, errorResponse, userInfo); 
    return errorResponse;
  }
}

Endpoint: /api/todo-demo

Method: POST

Description:

The /api/todo-demo endpoint allows authenticated users to create a new todo item. It utilizes the auth middleware to authenticate and authorize the user based on the provided OAuth token.

Request Headers:

  • Authorization: Bearer token obtained from the authentication process.

Request Body:

The request body should be in JSON format and include the following properties:

  • title (string): The title of the todo item.

  • description (string): The description of the todo item.

  • status (string): The status of the todo item.

Response:

  • Success: If the todo item is successfully created, the API will respond with a 200 OK status code and the created todo item in the response body.

  • Unauthorized: If the Authorization header is missing or the provided token is invalid, the API will respond with a 401 Unauthorized status code and an error message in the response body.

  • API Call Limit Exceeded: If the user has reached the maximum number of free API calls, the API will respond with a 429 Too Many Requests status code and an error message in the response body.

  • Server Error: If there is an error creating the todo item, the API will respond with a 500 Internal Server Error status code and an error message in the response body.

Auth Middleware:

The auth middleware is responsible for authenticating and authorizing the user based on the provided OAuth token. It performs the following steps:

  1. Checks if the request is a CORS preflight request and handles it accordingly.

  2. Retrieves the Authorization header from the request.

  3. Verifies the presence of the Authorization header. If missing, returns a 401 Unauthorized response.

  4. Extracts the OAuth token from the Authorization header.

  5. Sends a request to the user info endpoint (/api/oauth2/userinfo) with the OAuth token to retrieve user information.

  1. If the user info response is not successful, returns a 401 Unauthorized response.

  2. Parses the user info response and returns the user information.

  3. If there is an error fetching the user info, returns a 500 Internal Server Error response.

The auth middleware ensures that only authenticated and authorized users can access the protected API endpoints.

API Usage Limits:

The API implements usage limits to control the number of free API calls a user can make. The usage limits are defined in the API_USAGE_LIMITS_BY_CLIENT_ID constant based on the client ID.

Before creating a todo item, the API checks the current API call count for the user. If the count exceeds the maximum limit for the user's client ID, a 429 Too Many Requests response is returned.

After successfully creating a todo item, the API increments the API call count for the user.

Logging:

The API includes logging functionality to track API calls. The logApiCalls function is called after each API request to log the request details, response, and user information.

Error Handling:

The API handles errors gracefully and returns appropriate error responses. If there is an error creating a todo item, a 500 Internal Server Error response is returned with an error message.

Prisma ORM:

The API utilizes Prisma ORM to interact with the database. The prisma instance is imported from the @/utils/prisma.service module and is used to create the todo item in the database.

The Todo Demo API endpoint showcases the implementation of authorization and security using the auth middleware in the API. By leveraging the auth middleware, you can ensure that only authenticated and authorized users can access protected resources.

Additional Notes on ChatGPT and Authorization Headers

When integrating with ChatGPT, it's important to understand how it handles authorization and sends the necessary headers to your API endpoints.

ChatGPT will include the user's OAuth token in the Authorization header when making requests to your API. The format of the header will be as follows:

Authorization: Bearer [user's token]

In our API implementation, we have designed the auth middleware to expect and handle this specific format of the Authorization header. By extracting the token from the header and making a request to the user info endpoint (/api/oauth2/userinfo), we can retrieve the user's information and perform the necessary authentication and authorization checks.

This approach ensures that only authenticated users with valid tokens can access the protected API resources. It provides a secure and seamless integration between ChatGPT and our API endpoints.

Last updated