Protect Server Actions

What you'll cover in this guide

  • ✅ Set up a protected server action
  • ✅ Add a page that calls the server action
Using the Next.js Page Router? Note that Next.js Server Actions are available only with the App Router. If your app uses the Page Router, refer to our Next.js Page Router quickstart guide.

Before you get started

This guide assumes you have a Next.js project set up and running. If you haven't set up authentication in your Next.js App Router project yet, please refer to the quickstart guide.

Create a server action

First, let's define the server action. Create a file named action.ts in the src/app directory and add the following code:

src/app/actions.ts
"use server";

import { isAuthenticated } from "@monocloud/nextjs-auth";

export const action = async (data: FormData) => {
  const authenticated = await isAuthenticated();

  if (!authenticated) {
    console.log("User not authenticated");
  } else {
    console.log(data.get('name'));
  }
};

Let's review what this code does:

  1. We specify that the action should run on the server with the "use server"; directive.
  2. We check if the user is authenticated using the isAuthenticated() function imported from @monocloud/nextjs-auth. You could use getSession() here instead if you want to retrieve information about the user.
  3. If the user is not authenticated, we log a message to the console. Otherwise, we log the name passed in the form to the console.

Create a page that calls the action

Let's build a page that calls the server action we created above. Open src/app/page.tsx and replace the existing code with:

src/app/page.tsx
import { action } from "./actions";
import { isAuthenticated } from "@monocloud/nextjs-auth";
import { SignIn, SignOut } from "@monocloud/nextjs-auth/components";

export default async function ActionsPage() {
  const authenticated = await isAuthenticated();

  return (
    <div className="flex flex-col gap-3">
      <form action={action} className="flex gap-2">
        <input type="text" name="name" />
        <button type="submit">Submit</button>
      </form>
      {authenticated ? <SignOut>Sign Out</SignOut> : <SignIn>Sign In</SignIn>}
    </div>
  );
}

Let's review what this code does:

  1. We created a form that renders on the server and prompts the user for their name.
  2. The form's action attribute is set to the server-side action that we created above.
  3. If the user is logged in, the function will log the inputted name in the console. Otherwise "User not authenticated" will be outputted to the console.
The above approach will also work on client-side rendered pages.

See it in action by running:

Terminal
npm run dev

Then visit http://localhost:3000.

When the page loads, if you are already authenticated click the Sign Out button. Enter some text into the input field and click Submit. In the console, you'll see the message "User not authenticated".

Now click Sign In. Once you're signed in, try again by entering some text and clicking Submit. This time you should see a message in the console featuring the text you entered.