Middlewares not working in Better-auth integration
Unanswered
Argentine hake posted this in #help-forum
Argentine hakeOP
Hey!
I've been trying to implement better-auth in my nextjs project, but I'm running into weird issues where it seems my middlewares are not working.
(For reference, I've attached the folder structure)
I've been trying to implement better-auth in my nextjs project, but I'm running into weird issues where it seems my middlewares are not working.
(For reference, I've attached the folder structure)
15 Replies
@Argentine hake Hey!
I've been trying to implement better-auth in my nextjs project, but I'm running into weird issues where it seems my middlewares are not working.
(For reference, I've attached the folder structure)
Argentine hakeOP
import { NextRequest, NextResponse } from 'next/server';
import { headers } from 'next/headers';
import { auth } from '@/lib/auth';
export async function middleware(request: NextRequest) {
const session = await auth.api.getSession({
headers: await headers(),
});
if (!session) {
return NextResponse.redirect(new URL('/auth', request.url));
}
return NextResponse.next();
}
export const config = {
runtime: 'nodejs',
matcher: ['/profile/:path*', '/another/:path*', '/login'], // Apply middleware to specific routes
};
This is my middleware.ts file, I've used the auth function as mentioned in the better auth docs
import { betterAuth } from 'better-auth';
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
import { db } from '@/db';
import * as schema from '@/db/schema';
import { nextCookies } from 'better-auth/next-js';
import 'dotenv/config';
export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: 'pg',
schema,
}),
plugins: [nextCookies()], // Make sure this is the last plugin in the array
emailAndPassword: {
enabled: true,
},
});
@Argentine hake
import { NextRequest, NextResponse } from 'next/server';
import { headers } from 'next/headers';
import { auth } from '@/lib/auth';
export async function middleware(request: NextRequest) {
const session = await auth.api.getSession({
headers: await headers(),
});
if (!session) {
return NextResponse.redirect(new URL('/auth', request.url));
}
return NextResponse.next();
}
export const config = {
runtime: 'nodejs',
matcher: ['/profile/:path*', '/another/:path*', '/login'], // Apply middleware to specific routes
};
This is my middleware.ts file, I've used the auth function as mentioned in the better auth docs
import { betterAuth } from 'better-auth';
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
import { db } from '@/db';
import * as schema from '@/db/schema';
import { nextCookies } from 'better-auth/next-js';
import 'dotenv/config';
export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: 'pg',
schema,
}),
plugins: [nextCookies()], // Make sure this is the last plugin in the array
emailAndPassword: {
enabled: true,
},
});
Argentine hakeOP
Right now, both the routes are pretty much same so I'll share code for the /another route
This doesn't seem to work, but when I add the following things, it works
const AnotherPage = () => {
return (
<div className='flex flex-col items-center justify-center h-screen'>
<h1>Another Page</h1>
</div>
)
}
export default AnotherPage;
This doesn't seem to work, but when I add the following things, it works
import { auth } from "@/lib/auth";
import { headers } from "next/headers";
import { redirect } from "next/navigation";
const AnotherPage = async () => {
const session = await auth.api.getSession({
headers: await headers(),
});
if(!session) {
return redirect('/login');
}
return (
<div className='flex flex-col items-center justify-center h-screen'>
<h1>Another Page</h1>
</div>
)
}
export default AnotherPage;
@Argentine hake Right now, both the routes are pretty much same so I'll share code for the /another route
const AnotherPage = () => {
return (
<div className='flex flex-col items-center justify-center h-screen'>
<h1>Another Page</h1>
</div>
)
}
export default AnotherPage;
This doesn't seem to work, but when I add the following things, it works
import { auth } from "@/lib/auth";
import { headers } from "next/headers";
import { redirect } from "next/navigation";
const AnotherPage = async () => {
const session = await auth.api.getSession({
headers: await headers(),
});
if(!session) {
return redirect('/login');
}
return (
<div className='flex flex-col items-center justify-center h-screen'>
<h1>Another Page</h1>
</div>
)
}
export default AnotherPage;
Argentine hakeOP
So my point is, there is no other way I could handle this in a better way ?
I've to put
Code on every protected route ?
And on the login page, I've to do the vice versa, i.e. if the user already has a session redirect it to the protected routes ?
And it means that the middleware is not working at all?
I've to put
const session = await auth.api.getSession({
headers: await headers(),
});
if(!session) {
return redirect('/login');
}
Code on every protected route ?
And on the login page, I've to do the vice versa, i.e. if the user already has a session redirect it to the protected routes ?
And it means that the middleware is not working at all?
where is your middleware file located
Argentine hakeOP
It's currently in my root directory
I am using src folder to organise my code.
I tried googling a little bit tried putting it inside my src directory as well, in either case it doesn't seem to work
I am using src folder to organise my code.
I tried googling a little bit tried putting it inside my src directory as well, in either case it doesn't seem to work
And idts, my middleware is working at all, as I can't even see logs in my terminal if I put some console.log in it
I tried using llms, but each of them is just giving me different irrelavent answers (also a bit of existential crises)
From what I understand, it seem the middleware is suppose to run on edge so it doesn't have access to nodejs or other api calls, it can only access the headers, and the
requires interacting with the nodejs apis, but that still doesn't justify why not even my logs are not working in the middleware file
import { auth } from '@/lib/auth';
requires interacting with the nodejs apis, but that still doesn't justify why not even my logs are not working in the middleware file
I've attached my whole folder structure
what happens if you remove runtime:"nodejs"
@Yi Lon Ma what happens if you remove runtime:"nodejs"
Argentine hakeOP
nothings, ig I found it somewhere in the docs that this give the middleware access to the nodejs apis, so I added this.
this is very weird. Can you create a minimal reproduction repo?
@Yi Lon Ma this is very weird. Can you create a minimal reproduction repo?
Argentine hakeOP
yeah sure, just a bit, I am trying to figure out is it a nextjs issue or some bug in better auth
Argentine hakeOP
Finally figured it out,
The issue was that runtime: "nodejs", it was gas-lighting me in thinking that my middleware doesn't even exist.
So I did the following things
- Moved the middleware.ts to my src dirctory
- Removed that runtime: "nodejs" as in my project's nextjs version it was still experimental (I saw a post related to this being normal in nextjs 15.5 so yeah haven't tried it yet)
- Just checking the cookies inside the middleware and then in the layout file keeping a check for logged in or not (idk if it's the best or not, but it works so I am not touching it lol)
The issue was that runtime: "nodejs", it was gas-lighting me in thinking that my middleware doesn't even exist.
So I did the following things
- Moved the middleware.ts to my src dirctory
- Removed that runtime: "nodejs" as in my project's nextjs version it was still experimental (I saw a post related to this being normal in nextjs 15.5 so yeah haven't tried it yet)
- Just checking the cookies inside the middleware and then in the layout file keeping a check for logged in or not (idk if it's the best or not, but it works so I am not touching it lol)
Thanks a lot @Yi Lon Ma
apparently both of the things you pointed towards me was the fix
apparently both of the things you pointed towards me was the fix