Getting Started Next.js (App Router)

Install @tern-secure/nextjs and Firebase

First, you need to add the TernSecure Next.js package along with its peer dependencies, firebase and firebase-admin.

npm i @tern-secure/nextjs firebase firebase-admin

Core Setup

Protecting Routes with a Proxy

proxy.ts
import {
  ternSecureProxy,
  createRouteMatcher,
} from "@tern-secure/nextjs/server";

// Define public paths that do not require authentication.
const publicPaths = createRouteMatcher([
  "/api/auth/(.*)", 
  "/sign-in(.*)",
  "/sign-up(.*)",
]);

export const config = {
  matcher: [
    "/((?!_next|[^?]*.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico)).*)",
    "/(api|trpc)(.*)",
  ],
};

export default ternSecureProxy();

Creating the Auth API Handler

TernSecure needs a dedicated API route to handle authentication processes like creating, verifying, and refreshing sessions. Create the following file:

app/api/auth/[[...auth]]/route.ts
import { createTernSecureNextJsHandler } from "@tern-secure/nextjs/admin";
import { authHandlerOptions } from "@/lib/auth";

export const runtime = "nodejs";

const { GET, POST } = createTernSecureNextJsHandler(authHandlerOptions);

export { GET, POST };

Configuring the Auth Handler

The authHandlerOptions provide fine-grained control over cookies, security, and CORS settings. Create a new file to define these options.

lib/auth.ts
import { type TernSecureHandlerOptions } from "@tern-secure/nextjs/admin";

export const authHandlerOptions: TernSecureHandlerOptions = {
  cors: {
    allowedOrigins: [
      "http://localhost:3000",
      "https://your-production-domain.com",
    ],
    allowedMethods: ["GET", "POST"],
  },
  cookies: {
    httpOnly: true,
    sameSite: "strict",
    secure: process.env.NODE_ENV === "production",
    maxAge: 12 * 60 * 60 * 24, // 12 days
  },
  security: {
    allowedReferers: ["https://your-production-domain.com"],
  },
  revokeRefreshTokensOnSignOut: true,
  debug: process.env.NODE_ENV === "development",
};

Add TernSecureProvider to your app

app/layout.tsx
import { TernSecureProvider } from "@tern-secure/nextjs";

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return( 
    <TernSecureProvider>
      {children}
    </TernSecureProvider>
  );
}

Next Steps

Last updated on