Terrabythia
Terrabythia

Reputation: 2141

NextJS 12.2 middleware upgrade, return 401 basic auth

I'm trying to upgrade nextjs to v12.2+, which includes the change from using _middleware files on the page level to a global middleware file (https://nextjs.org/docs/messages/middleware-upgrade-guide). I've also read this guide that says I can no longer return a body in my middleware: https://nextjs.org/docs/messages/returning-response-body-in-middleware.

The problem I have now is that I want to show a Basic Auth prompt on specific pages, which was working in the old setup, but gives me the error "Middleware is returning a response body" in the new setup. I've tried to rewrite the code to use NextResponse.rewrite but that does not give me the basic auth prompt on the user's current page.

How would I rewrite this (old setup in /admin/_middleware.js):

import { NextResponse } from "next/server";

import checkBasicAuth from "@utils/middleware/checkBasicAuth";

export function middleware(req) {
  if (
    checkBasicAuth(req.headers.get("authorization"), {
      username: process.env.AUTH_USERNAME,
      password: process.env.AUTH_PASSWORD,
    })
  ) {
    return NextResponse.next();
  }
  return new Response("Authentication required", {
    status: 401,
    headers: {
      "WWW-Authenticate": 'Basic realm="Secure Area"',
    },
  });
}

to the new middleware setup (/src/middleware.js) so that the user does not get redirected, and gets the basic auth prompt when not logged in?

Upvotes: 3

Views: 5251

Answers (1)

Terrabythia
Terrabythia

Reputation: 2141

Found the answer myself, so for anyone stuck on the same problem, this is how I rewrote my old middleware:

import { NextResponse } from "next/server";

import checkBasicAuth from "@utils/middleware/checkBasicAuth";

export function middleware(request) {
  if (
    !checkBasicAuth(request.headers.get("authorization"), {
      username: process.env.AUTH_USERNAME,
      password: process.env.AUTH_PASSWORD,
    })
  ) {
    return NextResponse.rewrite(
      `${request.nextUrl.protocol}//${request.nextUrl.host}/401`,
      {
        status: 401,
        headers: {
          "WWW-Authenticate": 'Basic realm="Secure Area"',
        },
      }
    );
  }

  return NextResponse.next();
}

This will render but not redirect to the /401 error page, the custom header will make sure the basic auth dialog is shown to the user.

Upvotes: 3

Related Questions