-
I am trying to use withAuth in nextjs 13 middleware. I am using a database strategy with google and credentials providers Here is my middleware function: import { withAuth } from 'next-auth/middleware'
export default withAuth({
callbacks: {
authorized({ req, token }) {
return !!token
},
},
})
export const config = {
matcher: [
'/((?!api|_next/static|_next/image|favicon.ico).*)',
],
} The issue I am facing is token is always |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 5 replies
-
Unfortunately you can't use "For the time being, the withAuth middleware only supports "jwt" as session strategy." |
Beta Was this translation helpful? Give feedback.
-
as @MrEmanuel mentioned, I'm using my own Redis Adapter and facing same issue. You'll need to follow Advance usage: https://next-auth.js.org/configuration/nextjs#advanced-usage Note that Next Middleware uses Edge Runtime, so you can't access your database directly since at the context of Edge Runtime, there're limitations you'll probably need to create an extra API to call from middleware in order to get user session. For example: import { withAuth } from "next-auth/middleware"
export default withAuth(
// `withAuth` augments your `Request` with the user's token.
function middleware(req) {
console.log(req.nextauth.token)
},
{
callbacks: {
authorized: ({ token, req }) => {
// token here is null if you're using database strategy
try {
const res = await fetch('http://localhost:3000/api/get_my_session')
const json = await res.json()
// do your validation
return true / false
} catch(e) {
console.log(e)
return false
}
},
},
}
)
export const config = { matcher: ["/admin"] } |
Beta Was this translation helpful? Give feedback.
-
I havethe same issues. Token is always null, although I see the values in the request. There are different pitfalls possible, but I tried to have the most basic configuration, still no success. I ended up working around by:
I started debugging, but it's very cumbersome on that edge environment. Locally (with a production build) everything works, so I guess it's an issue with the edge environment. In case you like it, feel free to copy from: https://github.com/sesigl/learn-to-code-web/ |
Beta Was this translation helpful? Give feedback.
-
Ooof, finally. After so many time trying to fix this, nothing worked. let isAuthenticated = false;
request.headers.forEach((value, key) => {
if (value.includes(cookieName) || key.includes(cookieName)) {
isAuthenticated = true;
}
}); Note: This code ONLY checks for session cookie, it doesn't validate if it's still valid, or if it's even a valid session. You can make it more robust by validating the content in it correctly with your NEXTAUTH_SECRET env variable. This kept me blocked for more than 12 hours by now 😞, I need to deliver my MVP and don't care about this vulnerability in the first day 😆. |
Beta Was this translation helpful? Give feedback.
-
A work around for the problem is here!!Unfortunately those of us who are using alternate authentication methods such as session-based authentication don't have anything out of the box, and implementing a middleware like that yourself is trickier than you would expect, because you cannot simply pass the request in your middleware to getSession This seems to be because the next-auth accesses headers via req.headers.cookie, but the type of the headers inside middleware is not an object, but a Headers object which must be accessed through req.headers.get("cookie") I have implemented a middleware that works for session-based authentication. It does this by converting the relevant part of the request headers to an object import type { NextFetchEvent, NextRequest } from 'next/server';
import { getSession } from 'next-auth/react';
import { NextResponse } from 'next/server';
export async function middleware(req: NextRequest, ev: NextFetchEvent) {
const requestForNextAuth = {
headers: {
cookie: req.headers.get('cookie'),
},
};
const session = await getSession({ req: requestForNextAuth });
if (session) {
console.log(session);
// validate your session here
return NextResponse.next();
} else {
// the user is not logged in, redirect to the sign-in page
const signInPage = '/auth/signin';
const signInUrl = new URL(signInPage, req.nextUrl.origin);
signInUrl.searchParams.append('callbackUrl', req.url);
return NextResponse.redirect(signInUrl);
}
} However I think this means that an extra fetch call will be made to the next-auth backend. One in the middleware, and one later on if you want to access the session in API calls. |
Beta Was this translation helpful? Give feedback.
-
Hello @Ahmadh26, I noticed your issue with the token always being null in your Next.js 13 middleware when using next-auth. I had a similar problem and managed to resolve it. In my case, the root cause was the environment variables NEXTAUTH_URL and NEXT_PUBLIC_URL. They were incorrectly set to point to the production environment instead of localhost. While I understand this might not solve everyone's problem, issues with next-auth are often due to misconfiguration or incorrect coding, as it's a widely used library. Checking and correcting the environment variables could potentially resolve the issue for those experiencing similar problems. Hope this helps! |
Beta Was this translation helpful? Give feedback.
-
This is a workaround: export const { handlers, signIn, signOut, auth } = NextAuth({
adapter: DrizzleAdapter(getDatabaseClient(), {
usersTable: users,
accountsTable: accounts,
sessionsTable: sessions,
verificationTokensTable: verificationTokens,
}),
session: { strategy: "jwt" },
callbacks: {
session: async ({ session }) => {
const db = getDatabaseClient();
const user = await db.query.users.findFirst({
where: eq(users.email, session.user.email),
});
session.user = { ...user, ...session.user };
return session;
},
},
...authConfig,
}); |
Beta Was this translation helpful? Give feedback.
Unfortunately you can't use
withAuth
if you're using a session database strategy. It only works with a jwt session strategy.I'm trying to solve the same problem and haven't found a solution for it yet..
"For the time being, the withAuth middleware only supports "jwt" as session strategy."
https://next-auth.js.org/tutorials/securing-pages-and-api-routes#nextjs-middleware