Authentication & Security

Authentication is a vital part in protecting your app from malicious usage. In this section we'll go over how to protect different parts of the UploadThing flow.

Protecting the endpoint from spoofing

The callback request is like a webhook that is called by UploadThing when your file has been uploaded to the storage provider. The callback data is signed (HMAC SHA256) using the API key that uploaded the file. Since v6.7 of the Uploadthing SDK, the callback data is automatically verified before executing the callback. There is no additional work needed to protect the callback endpoint other than making sure you're on a version ^6.7 to ensure your endpoint is appropriately protected.

Protecting unauthenticated users from uploading files

You can protect unauthenticated users from uploading files via the .middleware() function in each file route. This makes it trivial to protect some file routes, and keep some public.

Using your favorite authentication provider (or self-roll if that's your thing), retrieve the current user's session from the incoming request. If it's not valid, you can throw an error which will terminate the upload flow. In the following example, we have a public file route that is protected by rate limiting, and a protected route that allows any authenticated user to upload files:

import { auth } from "auth";

import { createUploadthing, UploadThingError } from "uploadthing/server";

import { RateLimit } from "~/lib/ratelimit";

const ratelimiter = new RateLimit({
  /** rules */
});

export const uploadRouter = {
  publicRoute: f({ image: {} })
    .middleware(async ({ req }) => {
      const limit = await ratelimiter.verify(req);
      if (!limit.ok) {
        throw new UploadThingError("Rate limit exceeded");
      }

      return {};
    })
    .onUploadComplete(() => {
      /** ... */
    }),

  privateRoute: f({ image: {} })
    .middleware(async ({ req }) => {
      const session = await auth(req);
      if (!session) {
        throw new UploadThingError("You need to be logged in to upload files");
      }

      return { userId: session.user.id };
    })
    .onUploadComplete(() => {
      /** ... */
    }),
};

Was this page helpful?