Tutorial

Next.js Integration

Integrate AuthMe into a Next.js App Router project with server components, middleware guards, and API route protection.

Installation

Install the AuthMe SDK and the official OIDC client for Next.js.

Terminal
npm install authme-sdk next-auth@beta

Environment Variables

Add these variables to your .env.local:

.env.local
AUTHME_URL=https://auth.example.com
AUTHME_REALM=my-realm
AUTHME_CLIENT_ID=nextjs-app
AUTHME_CLIENT_SECRET=your-client-secret
NEXTAUTH_SECRET=your-random-secret
NEXTAUTH_URL=http://localhost:3000

AuthMe Provider Setup

Create auth.ts at the root of your project to configure the AuthMe OIDC provider.

auth.ts
// auth.ts — project root
import NextAuth from 'next-auth';

export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [
    {
      id: 'authme',
      name: 'AuthMe',
      type: 'oidc',
      issuer: `${process.env.AUTHME_URL}/realms/${process.env.AUTHME_REALM}`,
      clientId: process.env.AUTHME_CLIENT_ID,
      clientSecret: process.env.AUTHME_CLIENT_SECRET,
    },
  ],
  callbacks: {
    // Forward the access token to the session so you can call your API
    async jwt({ token, account }) {
      if (account) token.accessToken = account.access_token;
      return token;
    },
    async session({ session, token }) {
      session.accessToken = token.accessToken as string;
      return session;
    },
  },
});

Route Handler

Create the catch-all Auth.js route handler under app/api/auth/[...nextauth]/route.ts.

app/api/auth/[...nextauth]/route.ts
export { handlers as GET, handlers as POST } from '@/auth';

Middleware — Route Protection

Use Next.js middleware to protect entire route segments. Unauthenticated visitors are redirected to the sign-in page.

middleware.ts
export { auth as default } from '@/auth';

// Apply middleware only to these paths
export const config = {
  matcher: ['/dashboard/:path*', '/settings/:path*', '/api/protected/:path*'],
};

Server Component Auth

Access the session directly inside a React Server Component using the auth() helper — no client-side state required.

app/dashboard/page.tsx
import { auth } from '@/auth';
import { redirect } from 'next/navigation';

export default async function DashboardPage() {
  const session = await auth();

  if (!session) {
    redirect('/api/auth/signin');
  }

  return (
    <div>
      <h1>Welcome, {session.user?.name}</h1>
      <p>Email: {session.user?.email}</p>
    </div>
  );
}

API Route Protection

Protect Next.js API routes by verifying the session or validating the Bearer token with the AuthMe SDK.

app/api/protected/data/route.ts
import { auth } from '@/auth';
import { NextResponse } from 'next/server';

export async function GET() {
  const session = await auth();

  if (!session) {
    return NextResponse.json(
      { error: 'Unauthorized' },
      { status: 401 }
    );
  }

  return NextResponse.json({
    message: 'Protected data',
    user: session.user,
  });
}