Available for new projects,
consulting, and more.
Skip to content

Using Basic Auth middleware with Next.js

Simple, drop-in middleware for adding basic auth to your Next.js app

src/middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

const VALID_USERNAME = process.env.VALID_USERNAME
const VALID_PASSWORD = process.env.VALID_PASSWORD

export const config = {
  matcher: '/dashboard/:path*'
}

function unauthorized(message: string = 'Unauthorized') {
  return new NextResponse(message, {
    status: 401,
    headers: {
      'WWW-Authenticate': 'Basic realm="Secure Area"',
      'Content-Type': 'application/json',
    },
  })
}

function badRequest(message: string = 'Bad Request') {
  return new NextResponse(message, {
    status: 400,
    headers: {
      'Content-Type': 'application/json',
    },
  })
}

export function middleware(request: NextRequest) {
  const authHeader = request.headers.get('Authorization')

  if (!authHeader) {
    return unauthorized('Authorization header is required')
  }

  const [scheme, credentials] = authHeader.split(' ')

  if (scheme !== 'Basic') {
    return badRequest('Invalid authentication scheme')
  }

  try {
    const [username, password] = Buffer.from(credentials, 'base64')
      .toString()
      .split(':')

    if (!username || !password) {
      return badRequest('Invalid credentials format')
    }

    if (username !== VALID_USERNAME || password !== VALID_PASSWORD) {
      return unauthorized('Invalid credentials')
    }

    // User is authenticated
    return NextResponse.next()
  } catch (error) {
    // Handle base64 decode errors
    return badRequest('Invalid credentials encoding')
  }
}

All snippets