Logo
Published on

How to Add Basic Authentication in Next.js for Sitecore Headless Apps

Authors
  • avatar
    Name
    Jorge Lusar
    Twitter

Adding Basic Authentication to a Sitecore Headless App with Next.js Middleware

When building a Sitecore Headless application with Next.js, you’ll often deploy early builds to shared environments for QA, demos, or stakeholders. In those scenarios, you may not want your site publicly accessible until it’s ready. A quick solution is to protect your application with Basic Authentication.

In this post, I’ll walk through a simple MiddlewarePlugin implementation that adds Basic Authentication to a Next.js-powered Sitecore Headless app.


Why Basic Authentication?

Basic Authentication is not meant to replace robust identity management. It’s a lightweight mechanism to keep non-authorized users out of staging or preview environments. For example:

  • Protecting UAT environments from search engine indexing
  • Restricting demos to stakeholders only
  • Adding a quick security gate before full auth is integrated

It’s not recommended for production-level security, but it’s perfect for temporary locks.


The Middleware Plugin

Next.js 13 introduced Middleware, which allows you to run code before a request is completed. Sitecore’s Headless SDK enhances this concept with MiddlewarePlugins, giving us a nice way to extend request handling.

Here’s the implementation of a BasicAuthPlugin:

src/lib/middleware/plugins/basicauth.ts
import { NextRequest, NextResponse } from 'next/server';
import { MiddlewarePlugin } from '..';

class BasicAuthPlugin implements MiddlewarePlugin {
  order = 2;

  async exec(req: NextRequest, res?: NextResponse): Promise<NextResponse> {
    // Ignore if user is not setup
    const basicAuthUser = process.env.BASIC_AUTH_USER;
    const basicAuthPassword = process.env.BASIC_AUTH_PASSWORD;
    if (basicAuthUser === '' || basicAuthPassword === '') {
      return res || NextResponse.next();
    }

    const basicAuth = req.headers.get("authorization");
    if (basicAuth) {
      const authValue = basicAuth.split(" ")[1];
      const [username, pwd] = atob(authValue).split(":");
      if (username == basicAuthUser && pwd == basicAuthPassword) {
        return res || NextResponse.next();
      }
    }  

    return new NextResponse('Authentication required', {
      status: 401,
      headers: { 'WWW-Authenticate': 'Basic Realm=SecureZone' },
    });
  }
}

export const basicauthPlugin = new BasicAuthPlugin();

How It Works

  1. Environment Variables

    • Set up BASIC_AUTH_USER and BASIC_AUTH_PASSWORD in your environment.
    • If either is left empty, the plugin simply passes the request through (no auth required).
  2. Authorization Header

    • The middleware checks the Authorization header from the request.
    • If present, it decodes the Base64 value (username:password).
  3. Validation

    • If the provided credentials match the environment variables, the request continues.
    • If not, the middleware responds with a 401 Unauthorized status and a WWW-Authenticate header, prompting the browser to display a login dialog.

Setting It Up

  1. Add your credentials to .env (don’t commit these to source control):

    BASIC_AUTH_USER=myuser
    BASIC_AUTH_PASSWORD=mypassword
    
  2. Register the plugin in your middleware pipeline. Since it has order = 2, it will run after higher-priority plugins but before lower ones.

  3. Deploy to your environment. Now any request to your site will prompt for Basic Authentication.


When to Use This

✅ Great for:

  • QA / staging environments
  • Temporary demo sites
  • Quickly restricting access

❌ Not great for:

  • Production authentication
  • Handling multiple users/roles
  • Applications requiring fine-grained access control

For production, consider integrating Sitecore’s security features or a full identity provider (Azure AD, Auth0, etc.).


Wrapping Up

This simple middleware plugin is a practical way to add Basic Authentication to your Sitecore Headless Next.js application. It’s lightweight, environment-configurable, and easy to remove when you no longer need it.