[GH-ISSUE #1017] Better-Auth - Nextjs Middleware.ts didn't work properly #25874

Closed
opened 2026-04-17 16:10:56 -05:00 by GiteaMirror · 4 comments
Owner

Originally created by @daffafikri19 on GitHub (Dec 25, 2024).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/1017

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Install Nextjs 15
  2. Install Better-Auth & Prisma ORM Adapter
  3. Configure api/auth/...all/route.ts, env, auth server and client
  4. Create protected route and page for "/admin/dashboard"
  5. Add middleware.ts to root project directory, then copy following code instruction :
    from : https://www.better-auth.com/docs/integrations/next#middleware
    middleware.ts
    import { betterFetch } from "@better-fetch/fetch";
    import type { auth } from "@/lib/auth";
    import { NextResponse, type NextRequest } from "next/server";

type Session = typeof auth.$Infer.Session;

export default async function authMiddleware(request: NextRequest) {
const { data: session } = await betterFetch(
"/api/auth/get-session",
{
baseURL: request.nextUrl.origin,
headers: {
//get the cookie from the request
cookie: request.headers.get("cookie") || "",
},
},
);

if (!session) {
	return NextResponse.redirect(new URL("/auth/signin", request.url));
}
return NextResponse.next();

}

export const config = {
matcher: ["/admin/dashboard"],
};

Current vs. Expected behavior

As information in documentation that say :
In Next.js, middleware doesn’t have access to many Node APIs, so you can’t use the usual auth instance to validate sessions directly. Instead, you can make a request to the API route to get the session using the request headers.

I expected middleware.ts work for protecting our mentioned route. But what i got in "network" tab is fetch / hit api/auth/get-session is null (as i expected because im not authorized). In this case should be i redirected to auth/signin because no session there.
screenshot :
image

What version of Better Auth are you using?

1.1.1

Provide environment information

- OS : Windows 11
- Browser : Chrome

Which area(s) are affected? (Select all that apply)

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
import prisma from "./prisma";
import { headers } from "next/headers";

export const auth = betterAuth({
    database: prismaAdapter(prisma, {
        provider: "mysql",
    }),
    emailAndPassword: {
        enabled: true,
        autoSignIn: false
    },
    advanced: {
        cookiePrefix: "my-app"
    },
    plugins: []
});

// my callable instance auth for server-side component
export const useServerSession = async () => {
    const session = await auth.api.getSession({
        headers: (await headers())
    });

    return session
}

Additional context

No response

Originally created by @daffafikri19 on GitHub (Dec 25, 2024). Original GitHub issue: https://github.com/better-auth/better-auth/issues/1017 ### Is this suited for github? - [ ] Yes, this is suited for github ### To Reproduce 1. Install Nextjs 15 2. Install Better-Auth & Prisma ORM Adapter 3. Configure api/auth/[[...all]]/route.ts, env, auth server and client 4. Create protected route and page for "/admin/dashboard" 5. Add middleware.ts to root project directory, then copy following code instruction : from : https://www.better-auth.com/docs/integrations/next#middleware middleware.ts import { betterFetch } from "@better-fetch/fetch"; import type { auth } from "@/lib/auth"; import { NextResponse, type NextRequest } from "next/server"; type Session = typeof auth.$Infer.Session; export default async function authMiddleware(request: NextRequest) { const { data: session } = await betterFetch<Session>( "/api/auth/get-session", { baseURL: request.nextUrl.origin, headers: { //get the cookie from the request cookie: request.headers.get("cookie") || "", }, }, ); if (!session) { return NextResponse.redirect(new URL("/auth/signin", request.url)); } return NextResponse.next(); } export const config = { matcher: ["/admin/dashboard"], }; ### Current vs. Expected behavior As information in documentation that say : In Next.js, middleware doesn’t have access to many Node APIs, so you can’t use the usual auth instance to validate sessions directly. Instead, you can make a request to the API route to get the session using the request headers. I expected middleware.ts work for protecting our mentioned route. But what i got in "network" tab is fetch / hit api/auth/get-session is null (as i expected because im not authorized). In this case should be i redirected to auth/signin because no session there. screenshot : ![image](https://github.com/user-attachments/assets/321684ff-5d95-44e6-a5fd-202f8c29dda7) ### What version of Better Auth are you using? 1.1.1 ### Provide environment information ```bash - OS : Windows 11 - Browser : Chrome ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth"; import { prismaAdapter } from "better-auth/adapters/prisma"; import prisma from "./prisma"; import { headers } from "next/headers"; export const auth = betterAuth({ database: prismaAdapter(prisma, { provider: "mysql", }), emailAndPassword: { enabled: true, autoSignIn: false }, advanced: { cookiePrefix: "my-app" }, plugins: [] }); // my callable instance auth for server-side component export const useServerSession = async () => { const session = await auth.api.getSession({ headers: (await headers()) }); return session } ``` ### Additional context _No response_
GiteaMirror added the lockedbug labels 2026-04-17 16:10:56 -05:00
Author
Owner

@daffafikri19 commented on GitHub (Dec 25, 2024):

edited :
In code part
//get the cookie from the request
cookie: request.headers.get("cookie") || "",

i already change to cookie: request.headers.get("my-app")
still doesn't work

<!-- gh-comment-id:2561855162 --> @daffafikri19 commented on GitHub (Dec 25, 2024): edited : In code part //get the cookie from the request cookie: request.headers.get("cookie") || "", i already change to cookie: request.headers.get("my-app") still doesn't work
Author
Owner

@daveycodez commented on GitHub (Dec 26, 2024):

middleware.ts


import { getSession } from "@/lib/auth"

export async function middleware(request: NextRequest, event: NextFetchEvent) {
    const session = await getSession({ headers: request.headers })
}

This is how I'm getting session in middleware

<!-- gh-comment-id:2563057162 --> @daveycodez commented on GitHub (Dec 26, 2024): middleware.ts ```ts import { getSession } from "@/lib/auth" export async function middleware(request: NextRequest, event: NextFetchEvent) { const session = await getSession({ headers: request.headers }) } ``` This is how I'm getting session in middleware
Author
Owner

@moshetanzer commented on GitHub (Mar 25, 2025):

Hey @daffafikri19,

Did you manage to resolve your issue?

<!-- gh-comment-id:2752446205 --> @moshetanzer commented on GitHub (Mar 25, 2025): Hey @daffafikri19, Did you manage to resolve your issue?
Author
Owner

@Kinfe123 commented on GitHub (Apr 12, 2025):

this is also how i used to validate on the middleware with out node compat api's

import { NextRequest, NextResponse } from "next/server";
import { getSessionCookie } from "better-auth/cookies";

export async function middleware(request: NextRequest) {
	const cookies = getSessionCookie(request);
	if (!cookies) {
		return NextResponse.redirect(new URL("/", request.url));
	}
	return NextResponse.next();
}

export const config = {
	matcher: ["/dashboard"],
};

<!-- gh-comment-id:2798441028 --> @Kinfe123 commented on GitHub (Apr 12, 2025): this is also how i used to validate on the middleware with out node compat api's ```ts import { NextRequest, NextResponse } from "next/server"; import { getSessionCookie } from "better-auth/cookies"; export async function middleware(request: NextRequest) { const cookies = getSessionCookie(request); if (!cookies) { return NextResponse.redirect(new URL("/", request.url)); } return NextResponse.next(); } export const config = { matcher: ["/dashboard"], }; ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#25874