vercel / platforms

A full-stack Next.js app with multi-tenancy and custom domain support. Built with Next.js App Router and the Vercel Domains API.
https://app.vercel.pub
5.62k stars 734 forks source link

How to get this to work with next-auth v5? #381

Open trevorpfiz opened 8 months ago

trevorpfiz commented 8 months ago

Anyone have success getting the middleware to work with next-auth v5? I am wrapping the middleware in auth, but the req.url is whatever we set the AUTH_URL to be.

import { NextResponse } from "next/server";

import { auth } from "@nourish/auth";

import { env } from "~/env";
import { authRoutes } from "~/routes";

export const config = {
  matcher: [
    /*
     * Match all paths except for:
     * 1. /api routes
     * 2. /_next (Next.js internals)
     * 3. /_static (inside /public)
     * 4. all root files inside /public (e.g. /favicon.ico)
     */
    "/((?!api/|_next/|_static/|_vercel|[\\w-]+\\.\\w+).*)",
  ],
};

export default auth((req) => {
  const url = req.nextUrl;
  const isLoggedIn = !!req.auth;
  console.log(isLoggedIn, "isLoggedIn");

  // Get hostname of request (e.g. demo.vercel.pub, demo.localhost:3000)
  let hostname = req.headers
    .get("host")!
    .replace(".localhost:3000", `.${env.NEXT_PUBLIC_ROOT_DOMAIN}`);

  // special case for Vercel preview deployment URLs
  if (
    hostname.includes("---") &&
    hostname.endsWith(`.${process.env.NEXT_PUBLIC_VERCEL_DEPLOYMENT_SUFFIX}`)
  ) {
    hostname = `${hostname.split("---")[0]}.${env.NEXT_PUBLIC_ROOT_DOMAIN}`;
  }

  const searchParams = req.nextUrl.searchParams.toString();
  // Get the pathname of the request (e.g. /, /about, /blog/first-post)
  const path = `${url.pathname}${
    searchParams.length > 0 ? `?${searchParams}` : ""
  }`;

  console.log(hostname, path, url, req.url);

  // Handle app subdomain
  if (hostname == `app.${env.NEXT_PUBLIC_ROOT_DOMAIN}`) {
    if (!isLoggedIn && path !== "/signin") {
      return NextResponse.redirect(new URL("/signin", req.url));
    } else if (isLoggedIn && authRoutes.includes(path)) {
      return NextResponse.redirect(new URL("/", req.url));
    }

    return NextResponse.rewrite(
      new URL(`/app${path === "/" ? "" : path}`, req.url),
    );
  }

  // Handle main domain
  if (
    hostname === "localhost:3000" ||
    hostname === env.NEXT_PUBLIC_ROOT_DOMAIN
  ) {
    return NextResponse.rewrite(
      new URL(`/home${path === "/" ? "" : path}`, req.url),
    );
  }

  // Allow normal processing for all other requests
  return null;
});
trevorpfiz commented 8 months ago

Related #9631

alexanderbnelson commented 7 months ago

@trevorpfiz does the workaround you're using to account for the related nextauth issue #9631 get v5 working for you?

trevorpfiz commented 7 months ago

@trevorpfiz does the workaround you're using to account for the related nextauth issue #9631 get v5 working for you?

it did, but it seems that setting AUTH_URL in development is considered a legacy thing. if you need to change it look to use https://next-auth.js.org/getting-started/client#base-path or the format http://localhost:3000/api/auth instead of http://localhost:3000