Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exporting auth as middleware doesn't work #10912

Open
ShahriarKh opened this issue May 14, 2024 · 3 comments
Open

Exporting auth as middleware doesn't work #10912

ShahriarKh opened this issue May 14, 2024 · 3 comments
Labels
bug Something isn't working triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime.

Comments

@ShahriarKh
Copy link

ShahriarKh commented May 14, 2024

Environment

OS: Windows 10 10.0.19045
Node: 20.12.2
bun: 1.1.2

Firefox Developer Edition 126.0b9

next: 14.2.3 
next-auth: 5.0.0-beta.18
react: 18.3.1

Reproduction URL

https://github.com/ShahriarKh/middleware-test

Describe the issue

Using the method mentioned in the examples and also in the docs doesn't work at all.

export { auth as middleware } from 'auth'

export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};

I tried switching bun/Node, and also switching Next.js version (downgraded to 14.1.0 and 14.2.0 and both had the same issue)

I have to use a custom function like this, which is not desirable:

import { auth } from 'auth'

export default auth((req) => {
  if (!req.auth) {
    const url = req.url.replace(req.nextUrl.pathname, '/login');
    return Response.redirect(url);
  }
});

export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};

How to reproduce

Clone the app and visit / or /test.

Expected behavior

The middleware should automatically redirect to the login page if the request is unauthenticated.

@ShahriarKh ShahriarKh added bug Something isn't working triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime. labels May 14, 2024
@MateusTum
Copy link

Same error here!
The workaround that I found was using request cookies to check for session-token and validating it by using an api route. Here is my code:

// middleware.ts
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";

export async function middleware(req: NextRequest) {
  const cookies = req.cookies;

  if (!cookies.get("authjs.session-token")) {
    return NextResponse.redirect(new URL("/login", req.url));
  } else {
    try {
      const sessionResponse = await fetch(
        `${req.nextUrl.origin}/api/auth/session`,
        {
          headers: {
            cookie: req.headers.get("cookie") || "", // Pass cookies to the API route
          },
        }
      );
      if (sessionResponse.status !== 200) {
        throw new Error("Session not found");
      }
    } catch (error) {
      
      console.log(error);
      const response = NextResponse.redirect(new URL("/login", req.url));
      response.cookies.set('authjs.session-token', '', { expires: new Date(0) });
      return response;
    }
  }
  return NextResponse.next();
}

export const config = {
  matcher: "/admin/:path*",
};
// api/auth/session/route.ts
import { auth } from "@/auth";
import { NextResponse } from "next/server";
import { Session } from "next-auth";

export async function GET() {
  const session: Session | null = await auth();
  if (!session) {
    return NextResponse.json({ message: "Auth required" }, { status: 401 });
  }
  return NextResponse.json({ message: "succc" }, { status: 200 });
}

@neil-py
Copy link

neil-py commented May 22, 2024

Same error here! The workaround that I found was using request cookies to check for session-token and validating it by using an api route. Here is my code:

// middleware.ts
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";

export async function middleware(req: NextRequest) {
  const cookies = req.cookies;

  if (!cookies.get("authjs.session-token")) {
    return NextResponse.redirect(new URL("/login", req.url));
  } else {
    try {
      const sessionResponse = await fetch(
        `${req.nextUrl.origin}/api/auth/session`,
        {
          headers: {
            cookie: req.headers.get("cookie") || "", // Pass cookies to the API route
          },
        }
      );
      if (sessionResponse.status !== 200) {
        throw new Error("Session not found");
      }
    } catch (error) {
      
      console.log(error);
      const response = NextResponse.redirect(new URL("/login", req.url));
      response.cookies.set('authjs.session-token', '', { expires: new Date(0) });
      return response;
    }
  }
  return NextResponse.next();
}

export const config = {
  matcher: "/admin/:path*",
};
// api/auth/session/route.ts
import { auth } from "@/auth";
import { NextResponse } from "next/server";
import { Session } from "next-auth";

export async function GET() {
  const session: Session | null = await auth();
  if (!session) {
    return NextResponse.json({ message: "Auth required" }, { status: 401 });
  }
  return NextResponse.json({ message: "succc" }, { status: 200 });
}

This workaround works so far. I hope a fix will be released soon

@bibblebabl
Copy link

I am also experiencing a problem with incorrect req type definition in middleware. Is it the same for you?

No overload matches this call.
  Overload 1 of 4, '(args_0: GetServerSidePropsContext): Promise<Session | null>', gave the following error.
    Argument of type '(req: NextAuthRequest) => Response | null' is not assignable to parameter of type 'GetServerSidePropsContext'.
  Overload 2 of 4, '(args_0: (req: NextAuthRequest, ctx: AppRouteHandlerFnContext) => void | Response | Promise<void | Response>): AppRouteHandlerFn', gave the following error.
    Argument of type '(req: NextAuthRequest) => Response | null' is not assignable to parameter of type '(req: NextAuthRequest, ctx: AppRouteHandlerFnContext) => void | Response | Promise<void | Response>'.
      Type 'Response | null' is not assignable to type 'void | Response | Promise<void | Response>'.
        Type 'null' is not assignable to type 'void | Response | Promise<void | Response>'.ts(2769)
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime.
Projects
None yet
Development

No branches or pull requests

4 participants