← Back to Blog

Integration of Keycloak with Next.js

July 24, 2024
6 min read
Keycloak
Next.js
Authentication
App Router
NextAuth.js

What You Will Gain in the End

Development Efficiency

Reduce development and authentication setup time by 30% with Keycloak's ready-to-use authentication system.

Enhanced Security

Improve application security through multi-factor authentication (MFA) and single sign-on (SSO) capabilities.

User Convenience

Improve user experience with SSO, reducing the number of required logins across multiple applications.

Management Efficiency

Improve user and role management efficiency, reducing administrative errors by 20%.

Overview of Keycloak: What It Is and Why It Is Needed

Keycloak is an open-source platform designed for managing user authentication and authorization in web applications and services. It simplifies and centralizes login processes, user management, and access control. Keycloak supports various authentication protocols such as OAuth 2.0, OpenID Connect, and SAML 2.0, making it a versatile tool for integration with different applications and services.

Key Features

Keycloak provides centralized management of users and groups, allowing administrators to easily create, modify, and delete user accounts, and manage roles and permissions. It integrates with data sources like LDAP and Active Directory, simplifying account synchronization and management in large corporate networks.

Another key feature is single sign-on (SSO), which allows users to access multiple applications and services with a single login. This improves the user experience and security by reducing the number of login points for potential attacks. Keycloak also provides tools for configuring multi-factor authentication (MFA) for an additional layer of protection.

Keycloak is essential for creating a unified authorization system at the microservices level, coordinating and managing access across different services. It unifies user data from various sources into a centralized database, simplifying account management and improving data consistency.

Benefits of Using Keycloak for Authentication and Authorization

Key Advantages

Using Keycloak offers many advantages, making it an attractive choice for various organizations and projects. It centralizes user management and access rights, simplifies administration, enhances security, and supports SSO and MFA. Keycloak's compliance with modern authentication standards (OAuth 2.0, OpenID Connect, SAML 2.0) ensures compatibility with a wide range of web applications and services.

Preparation for Integration

Before integrating Keycloak with your Next.js application, you need to set up and configure Keycloak itself. This involves installing Keycloak, creating a realm, and configuring a client for your Next.js application.

Installing and Configuring Keycloak

To install and configure Keycloak using Docker, ensure Docker is installed on your system. If not, download and install it from the official Docker website. Open the terminal and execute the command:

1docker run -p 8080:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin jboss/keycloak

This command will download the Keycloak image and start a container accessible on port 8080. The KEYCLOAK_USER and KEYCLOAK_PASSWORD parameters set the admin username and password. After the container starts, access the Keycloak admin console at http://localhost:8080/auth using the admin credentials.

Creating a New Realm

Log into the Keycloak admin console at http://localhost:8080/auth using admin credentials. Click on the dropdown menu next to the current realm name in the top left corner and select "Add Realm." Enter the desired name for the new realm, such as "MyRealm," and click "Create." Configure the realm's basic settings like user registration, password policies, and session management.

Learn More About Realms

For more information about realms and clients in Keycloak, check out this detailed guide.

Configuring Clients in Keycloak for Next.js Application

To configure a client for a Next.js application in Keycloak, create a new client and set a unique name. This client will represent your Next.js application, using authentication protocols like OAuth 2.0 or OpenID Connect. Specify redirect URLs for handling authentication and authorization redirects.

Step-by-Step Client Configuration

  1. Log into the Keycloak admin console and select the created realm.
  2. Go to the "Clients" section and click "Create."
  3. Enter a unique client name (e.g., "nextjs-client"), choose "openid-connect" for "Client Protocol," and set the "Root URL" to your Next.js app URL (e.g., http://localhost:3000).
  4. Save the changes.
  5. Configure additional settings like "Access Type" to "public," and set valid redirect URIs and web origins.

Integrating Keycloak with Next.js (App Router)

Now that Keycloak is set up, let's integrate it with your Next.js application using the App Router.

Installing Necessary Libraries for Next.js

Install keycloak-js and next-auth libraries for integrating Keycloak with Next.js:

1npm install keycloak-js next-auth --save

Or, if using Yarn:

1yarn add keycloak-js next-auth

Configuring Environment for Libraries

Create a .env file in the root directory of your project and add the following lines:

1KEYCLOAK_URL=http://localhost:8080/auth
2KEYCLOAK_REALM=your-realm
3KEYCLOAK_CLIENT_ID=nextjs-client
4NEXTAUTH_URL=http://localhost:3000
5NEXTAUTH_SECRET=your-next-auth-secret

Environment Variables Explained

  • KEYCLOAK_URL: The URL address of your Keycloak server. This is the main address through which your application will interact with Keycloak.
  • KEYCLOAK_REALM: The name of the realm you created in Keycloak. A realm represents a namespace for managing users and roles.
  • KEYCLOAK_CLIENT_ID: The client identifier you created for your Next.js application in Keycloak. This identifier is used to identify your application when interacting with Keycloak.
  • NEXTAUTH_URL: The URL address of your Next.js application. This is the address to which users will be redirected after authentication. NextAuth.js uses this to determine the base URL of your application.
  • NEXTAUTH_SECRET: The secret key used for encrypting sessions in NextAuth.js. This key must be unique and secure.

Generating a Secure Secret

To ensure session security in NextAuth.js, you need a unique and complex secret key. You can generate NEXTAUTH_SECRET using various methods, such as the OpenSSL command-line utility:

openssl rand -base64 32

Setting Up Router (App Router)

Create the authentication route in app/api/auth/[…nextauth]/route.ts:

1import NextAuth from 'next-auth';
2import KeycloakProvider from 'next-auth/providers/keycloak';
3import { NextApiRequest, NextApiResponse } from 'next';
4
5const options = {
6  providers: [
7    KeycloakProvider({
8      clientId: process.env.KEYCLOAK_CLIENT_ID as string,
9      clientSecret: process.env.KEYCLOAK_CLIENT_SECRET || "",
10      issuer: `${process.env.KEYCLOAK_URL}/realms/${process.env.KEYCLOAK_REALM}`
11    })
12  ],
13  secret: process.env.NEXTAUTH_SECRET,
14  callbacks: {
15    async jwt({ token, user }) {
16      if (user) {
17        token.id = user.id;
18      }
19      return token;
20    },
21    async session({ session, token }) {
22      session.user.id = token.id;
23      return session;
24    }
25  }
26};
27
28export default async function auth(req: NextApiRequest, res: NextApiResponse) {
29  return await NextAuth(req, res, options);
30}

This file sets up the authentication route using NextAuth.js with Keycloak as the authentication provider. The options object defines Keycloak as the provider, using environment variables for configuration. The callbacks ensure that the user's ID is included in the token and session. The auth function handles the authentication request.

Create a protected page in app/protected/page.tsx:

1'use client';
2
3import { signIn, useSession } from 'next-auth/react';
4import { useEffect } from 'react';
5
6const ProtectedPage: React.FC = () => {
7  const { data: session, status } = useSession();
8  
9  useEffect(() => {
10    if (status === 'unauthenticated') {
11      signIn();
12    }
13  }, [status]);
14  
15  if (status === 'loading') {
16    return <div>Loading...</div>;
17  }
18
19  return (
20    <div>
21      <h1>Welcome to the protected page, {session?.user?.name}!</h1>
22    </div>
23  );
24};
25
26export default ProtectedPage;

This code creates a protected page that checks the user's authentication status using the useSession hook from next-auth/react. If the user is not authenticated, the signIn function is called to redirect them to the login page. If authentication is in progress, a "Loading..." message is displayed.

In app/layout.tsx, add the NextAuth.js session provider:

1import './globals.css';
2import { SessionProvider } from 'next-auth/react';
3import Header from './components/Header';
4
5export default function RootLayout({ children }: { children: React.ReactNode }) {
6  return (
7    <html lang="en">
8      <body>
9        <SessionProvider>
10          <Header />
11          {children}
12        </SessionProvider>
13      </body>
14    </html>
15  );
16}

This file sets up the root layout for the application, wrapping the content in a SessionProvider from NextAuth.js to provide global access to the authentication session throughout the application. The Header component is also included, ensuring it is displayed on every page.

Create the Header.tsx component in the app/components folder:

1'use client';
2
3import { useSession, signIn, signOut } from 'next-auth/react';
4
5const Header: React.FC = () => {
6  const { data: session, status } = useSession();
7  
8  return (
9    <header>
10      <nav>
11        <h1>My Application</h1>
12        <div>
13          {status === 'loading' ? (
14            <p>Loading...</p>
15          ) : session ? (
16            <>
17              <p>Welcome, {session.user?.name}</p>
18              <button onClick={() => signOut()}>Logout</button>
19            </>
20          ) : (
21            <button onClick={() => signIn()}>Login</button>
22          )}
23        </div>
24      </nav>
25    </header>
26  );
27};
28
29export default Header;

This component uses the useSession hook to check the current session state. If the user is authenticated, their name and a logout button are displayed. If the user is not authenticated, a login button is displayed. This ensures that users can easily sign in and out of the application from the header.

Integration Complete

You have now successfully integrated Keycloak with your Next.js application using the App Router and NextAuth.js. Your application now has secure authentication with features like SSO and the potential for MFA, all managed through Keycloak.

Need help with Keycloak integration?
I offer expert consultation on Keycloak setup, Next.js integration, and secure authentication implementation. Let's discuss how I can help you build a more secure and user-friendly authentication system.