Enterprise-Level Authentication in a Containerized Environment for Next.js 13 - AuthJS Patch

Enterprise-Level Authentication in a Containerized Environment for Next.js 13 - AuthJS Patch

Recently, I've published a step by step guide on Enterprise-Level Authentication in a Containerized Environment for NextJS and while searching on the internet I saw a post on Keycloak groups. benmarte was having a problem while integrating Keycloak using auth.js instead of next-auth. In this post I'll explain how you can handle authentication using auth.js.

To get the most out of this post please setup your environment as I shared in my previous post.



NextJS 13 Keycloak Integration Using AuthJS

  1. Install AuthJS as it is suggested in official documentation:
npm install next-auth@beta
  1. Create .env.local file in the root directory of your next-app project and add the following:

You can use following commands to produce AUTH_SECRET value. This secret is used to sign and encrypt cookies.
You can see where to find other values in my PREVIOUS POST.
openssl rand -base64 33


npx auth secret
  1. Create /types folder in your projects root and create node-env.d.ts file in it.
// /types/node-env.d.ts
declare namespace NodeJS {
    export interface ProcessEnv {
  1. Create auth.ts file under your /src directory and add the following code:
// /src/auth.ts
import NextAuth from "next-auth"
import Keycloak from "next-auth/providers/keycloak";

export const { handlers, signIn, signOut, auth } = NextAuth({
  providers: [
      jwks_endpoint: `${process.env.NEXT_CONTAINER_KEYCLOAK_ENDPOINT}/realms/myrealm/protocol/openid-connect/certs`,
      wellKnown: undefined,
      clientId: process.env.NEXT_PUBLIC_KEYCLOAK_CLIENT_ID,
      clientSecret: process.env.KEYCLOAK_CLIENT_SECRET,
      issuer: `${process.env.NEXT_LOCAL_KEYCLOAK_URL}/realms/${process.env.NEXT_PUBLIC_KEYCLOAK_REALM}`,
      authorization: {
        params: {
          scope: "openid email profile",
        url: `${process.env.NEXT_LOCAL_KEYCLOAK_URL}/realms/myrealm/protocol/openid-connect/auth`,
      token: `${process.env.NEXT_CONTAINER_KEYCLOAK_ENDPOINT}/realms/myrealm/protocol/openid-connect/token`,
      userinfo: `${process.env.NEXT_CONTAINER_KEYCLOAK_ENDPOINT}/realms/myrealm/protocol/openid-connect/userinfo`,
This part is important! We must use any kind of parameter indicating urls as localhost but urls used for sending a request must use container name for connectivity purposes through docker network.
  1. Now it's time to create our route.ts and it must be in /src/app/api/auth/[...nextauth]/route.ts
// /src/app/api/auth/[...nextauth]/route.ts

import { handlers } from "@/auth";
export const { GET, POST } = handlers;
  1. We are going to need a Sign-In component! Let's create It. Create a components folder under your /src directory and create a file as sign-in.tsx.
// /src/components/sign-in.tsx

import { signIn } from "@/auth"

export function SignIn() {
  return (
      action={async () => {
        "use server"
        await signIn("keycloak")
      <button type="submit">Signin with Keycloak</button>
  1. It's time to replace our src/app/page.tsx :
// src/app/page.tsx
import { auth } from "@/auth";
import { SignIn } from "../components/sign-in";

export default async function Home() {
  const session = await auth();
  if (session) {
    return (
        <div>Your name is {session.user?.name}</div>
  return (
      <SignIn />

Congratulations 👏 You've done it. You just implemented an Enterprise-Level Authentication in a Containerized Environment for Next.js 13 using AuthJS instead of NextAuth !

docker compose -f docker-compose.dev.yml build
docker compose -f docker-compose.dev.yml up -d

Thank you and see you soon!